* Makefile.in (C_COMMON_OBJS): Depend on c-cilkplus.o.
[official-gcc.git] / gcc / tree-profile.c
blobf3f97b2e0dc0b5667740cb04dc770eae325192b5
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"
52 static GTY(()) tree gcov_type_node;
53 static GTY(()) tree tree_interval_profiler_fn;
54 static GTY(()) tree tree_pow2_profiler_fn;
55 static GTY(()) tree tree_one_value_profiler_fn;
56 static GTY(()) tree tree_indirect_call_profiler_fn;
57 static GTY(()) tree tree_time_profiler_fn;
58 static GTY(()) tree tree_average_profiler_fn;
59 static GTY(()) tree tree_ior_profiler_fn;
62 static GTY(()) tree ic_void_ptr_var;
63 static GTY(()) tree ic_gcov_type_ptr_var;
64 static GTY(()) tree ptr_void;
66 /* Do initialization work for the edge profiler. */
68 /* Add code:
69 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
70 __thread void* __gcov_indirect_call_callee; // actual callee address
71 __thread int __gcov_function_counter; // time profiler function counter
73 static void
74 init_ic_make_global_vars (void)
76 tree gcov_type_ptr;
78 ptr_void = build_pointer_type (void_type_node);
80 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
81 if (flag_lto)
83 ic_void_ptr_var
84 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
85 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
86 ptr_void);
87 TREE_PUBLIC (ic_void_ptr_var) = 1;
88 DECL_COMMON (ic_void_ptr_var) = 1;
89 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
90 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
92 else
94 ic_void_ptr_var
95 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
96 get_identifier ("__gcov_indirect_call_callee"),
97 ptr_void);
98 TREE_PUBLIC (ic_void_ptr_var) = 1;
99 DECL_EXTERNAL (ic_void_ptr_var) = 1;
101 TREE_STATIC (ic_void_ptr_var) = 1;
102 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
103 DECL_INITIAL (ic_void_ptr_var) = NULL;
104 if (targetm.have_tls)
105 DECL_TLS_MODEL (ic_void_ptr_var) =
106 decl_default_tls_model (ic_void_ptr_var);
108 varpool_finalize_decl (ic_void_ptr_var);
110 gcov_type_ptr = build_pointer_type (get_gcov_type ());
111 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
112 if (flag_lto)
114 ic_gcov_type_ptr_var
115 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
116 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
117 gcov_type_ptr);
118 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
119 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
120 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
121 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
123 else
125 ic_gcov_type_ptr_var
126 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
127 get_identifier ("__gcov_indirect_call_counters"),
128 gcov_type_ptr);
129 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
130 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
132 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
133 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
134 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
135 if (targetm.have_tls)
136 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
137 decl_default_tls_model (ic_gcov_type_ptr_var);
139 varpool_finalize_decl (ic_gcov_type_ptr_var);
142 /* Create the type and function decls for the interface with gcov. */
144 void
145 gimple_init_edge_profiler (void)
147 tree interval_profiler_fn_type;
148 tree pow2_profiler_fn_type;
149 tree one_value_profiler_fn_type;
150 tree gcov_type_ptr;
151 tree ic_profiler_fn_type;
152 tree average_profiler_fn_type;
153 tree time_profiler_fn_type;
155 if (!gcov_type_node)
157 gcov_type_node = get_gcov_type ();
158 gcov_type_ptr = build_pointer_type (gcov_type_node);
160 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
161 interval_profiler_fn_type
162 = build_function_type_list (void_type_node,
163 gcov_type_ptr, gcov_type_node,
164 integer_type_node,
165 unsigned_type_node, NULL_TREE);
166 tree_interval_profiler_fn
167 = build_fn_decl ("__gcov_interval_profiler",
168 interval_profiler_fn_type);
169 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
170 DECL_ATTRIBUTES (tree_interval_profiler_fn)
171 = tree_cons (get_identifier ("leaf"), NULL,
172 DECL_ATTRIBUTES (tree_interval_profiler_fn));
174 /* void (*) (gcov_type *, gcov_type) */
175 pow2_profiler_fn_type
176 = build_function_type_list (void_type_node,
177 gcov_type_ptr, gcov_type_node,
178 NULL_TREE);
179 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
180 pow2_profiler_fn_type);
181 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
182 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
183 = tree_cons (get_identifier ("leaf"), NULL,
184 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
186 /* void (*) (gcov_type *, gcov_type) */
187 one_value_profiler_fn_type
188 = build_function_type_list (void_type_node,
189 gcov_type_ptr, gcov_type_node,
190 NULL_TREE);
191 tree_one_value_profiler_fn
192 = build_fn_decl ("__gcov_one_value_profiler",
193 one_value_profiler_fn_type);
194 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
195 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
196 = tree_cons (get_identifier ("leaf"), NULL,
197 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
199 init_ic_make_global_vars ();
201 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
202 if (flag_lto)
204 /* void (*) (gcov_type, void *) */
205 ic_profiler_fn_type
206 = build_function_type_list (void_type_node,
207 gcov_type_ptr, gcov_type_node,
208 ptr_void, ptr_void,
209 NULL_TREE);
210 tree_indirect_call_profiler_fn
211 = build_fn_decl ("__gcov_indirect_call_profiler",
212 ic_profiler_fn_type);
214 else
216 /* void (*) (gcov_type, void *) */
217 ic_profiler_fn_type
218 = build_function_type_list (void_type_node,
219 gcov_type_node,
220 ptr_void,
221 NULL_TREE);
222 tree_indirect_call_profiler_fn
223 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
224 ic_profiler_fn_type);
226 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
227 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
228 = tree_cons (get_identifier ("leaf"), NULL,
229 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
231 /* void (*) (gcov_type *, gcov_type, void *) */
232 time_profiler_fn_type
233 = build_function_type_list (void_type_node,
234 gcov_type_ptr, NULL_TREE);
235 tree_time_profiler_fn
236 = build_fn_decl ("__gcov_time_profiler",
237 time_profiler_fn_type);
238 TREE_NOTHROW (tree_time_profiler_fn) = 1;
239 DECL_ATTRIBUTES (tree_time_profiler_fn)
240 = tree_cons (get_identifier ("leaf"), NULL,
241 DECL_ATTRIBUTES (tree_time_profiler_fn));
243 /* void (*) (gcov_type *, gcov_type) */
244 average_profiler_fn_type
245 = build_function_type_list (void_type_node,
246 gcov_type_ptr, gcov_type_node, NULL_TREE);
247 tree_average_profiler_fn
248 = build_fn_decl ("__gcov_average_profiler",
249 average_profiler_fn_type);
250 TREE_NOTHROW (tree_average_profiler_fn) = 1;
251 DECL_ATTRIBUTES (tree_average_profiler_fn)
252 = tree_cons (get_identifier ("leaf"), NULL,
253 DECL_ATTRIBUTES (tree_average_profiler_fn));
254 tree_ior_profiler_fn
255 = build_fn_decl ("__gcov_ior_profiler",
256 average_profiler_fn_type);
257 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
258 DECL_ATTRIBUTES (tree_ior_profiler_fn)
259 = tree_cons (get_identifier ("leaf"), NULL,
260 DECL_ATTRIBUTES (tree_ior_profiler_fn));
262 /* LTO streamer needs assembler names. Because we create these decls
263 late, we need to initialize them by hand. */
264 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
265 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
266 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
267 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
268 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
269 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
270 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
274 /* Output instructions as GIMPLE trees to increment the edge
275 execution count, and insert them on E. We rely on
276 gsi_insert_on_edge to preserve the order. */
278 void
279 gimple_gen_edge_profiler (int edgeno, edge e)
281 tree ref, one, gcov_type_tmp_var;
282 gimple stmt1, stmt2, stmt3;
284 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
285 one = build_int_cst (gcov_type_node, 1);
286 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
287 NULL, "PROF_edge_counter");
288 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
289 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
290 NULL, "PROF_edge_counter");
291 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
292 gimple_assign_lhs (stmt1), one);
293 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
294 gsi_insert_on_edge (e, stmt1);
295 gsi_insert_on_edge (e, stmt2);
296 gsi_insert_on_edge (e, stmt3);
299 /* Emits code to get VALUE to instrument at GSI, and returns the
300 variable containing the value. */
302 static tree
303 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
305 tree val = value->hvalue.value;
306 if (POINTER_TYPE_P (TREE_TYPE (val)))
307 val = fold_convert (build_nonstandard_integer_type
308 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
309 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
310 true, NULL_TREE, true, GSI_SAME_STMT);
313 /* Output instructions as GIMPLE trees to increment the interval histogram
314 counter. VALUE is the expression whose value is profiled. TAG is the
315 tag of the section for counters, BASE is offset of the counter position. */
317 void
318 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
320 gimple stmt = value->hvalue.stmt;
321 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
322 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
323 gimple call;
324 tree val;
325 tree start = build_int_cst_type (integer_type_node,
326 value->hdata.intvl.int_start);
327 tree steps = build_int_cst_type (unsigned_type_node,
328 value->hdata.intvl.steps);
330 ref_ptr = force_gimple_operand_gsi (&gsi,
331 build_addr (ref, current_function_decl),
332 true, NULL_TREE, true, GSI_SAME_STMT);
333 val = prepare_instrumented_value (&gsi, value);
334 call = gimple_build_call (tree_interval_profiler_fn, 4,
335 ref_ptr, val, start, steps);
336 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
339 /* Output instructions as GIMPLE trees to increment the power of two histogram
340 counter. VALUE is the expression whose value is profiled. TAG is the tag
341 of the section for counters, BASE is offset of the counter position. */
343 void
344 gimple_gen_pow2_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 gimple 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_pow2_profiler_fn, 2, ref_ptr, val);
356 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
359 /* Output instructions as GIMPLE trees for code to find the most common value.
360 VALUE is the expression whose value is profiled. TAG is the tag of the
361 section for counters, BASE is offset of the counter position. */
363 void
364 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
366 gimple stmt = value->hvalue.stmt;
367 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
368 tree ref_ptr = tree_coverage_counter_addr (tag, base);
369 gimple call;
370 tree val;
372 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
373 true, NULL_TREE, true, GSI_SAME_STMT);
374 val = prepare_instrumented_value (&gsi, value);
375 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
376 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
380 /* Output instructions as GIMPLE trees for code to find the most
381 common called function in indirect call.
382 VALUE is the call expression whose indirect callee is profiled.
383 TAG is the tag of the section for counters, BASE is offset of the
384 counter position. */
386 void
387 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
389 tree tmp1;
390 gimple stmt1, stmt2, stmt3;
391 gimple stmt = value->hvalue.stmt;
392 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
393 tree ref_ptr = tree_coverage_counter_addr (tag, base);
395 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
396 true, NULL_TREE, true, GSI_SAME_STMT);
398 /* Insert code:
400 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
401 stmt2: tmp1 = (void *) (indirect call argument value)
402 stmt3: __gcov_indirect_call_callee = tmp1;
405 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
406 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
407 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
408 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
410 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
411 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
412 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
416 /* Output instructions as GIMPLE trees for code to find the most
417 common called function in indirect call. Insert instructions at the
418 beginning of every possible called function.
421 void
422 gimple_gen_ic_func_profiler (void)
424 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
425 gimple_stmt_iterator gsi;
426 gimple stmt1, stmt2;
427 tree tree_uid, cur_func, void0;
429 if (cgraph_only_called_directly_p (c_node))
430 return;
432 gimple_init_edge_profiler ();
434 /* Insert code:
436 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
437 &current_function_decl)
439 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR)));
441 cur_func = force_gimple_operand_gsi (&gsi,
442 build_addr (current_function_decl,
443 current_function_decl),
444 true, NULL_TREE,
445 true, GSI_SAME_STMT);
446 tree_uid = build_int_cst
447 (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
448 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
449 if (flag_lto)
451 tree counter_ptr, ptr_var;
452 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
453 true, NULL_TREE, true,
454 GSI_SAME_STMT);
455 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
456 true, NULL_TREE, true,
457 GSI_SAME_STMT);
459 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
460 counter_ptr, tree_uid, cur_func, ptr_var);
462 else
464 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
465 tree_uid, cur_func);
467 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
469 /* Set __gcov_indirect_call_callee to 0,
470 so that calls from other modules won't get misattributed
471 to the last caller of the current callee. */
472 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
473 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
474 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
477 /* Output instructions as GIMPLE tree at the beginning for each function.
478 TAG is the tag of the section for counters, BASE is offset of the
479 counter position and GSI is the iterator we place the counter. */
481 void
482 gimple_gen_time_profiler (unsigned tag, unsigned base,
483 gimple_stmt_iterator &gsi)
485 tree ref_ptr = tree_coverage_counter_addr (tag, base);
486 gimple call;
488 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
489 true, NULL_TREE, true, GSI_SAME_STMT);
490 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
491 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
494 /* Output instructions as GIMPLE trees for code to find the most common value
495 of a difference between two evaluations of an expression.
496 VALUE is the expression whose value is profiled. TAG is the tag of the
497 section for counters, BASE is offset of the counter position. */
499 void
500 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
501 unsigned tag ATTRIBUTE_UNUSED,
502 unsigned base ATTRIBUTE_UNUSED)
504 /* FIXME implement this. */
505 #ifdef ENABLE_CHECKING
506 internal_error ("unimplemented functionality");
507 #endif
508 gcc_unreachable ();
511 /* Output instructions as GIMPLE trees to increment the average histogram
512 counter. VALUE is the expression whose value is profiled. TAG is the
513 tag of the section for counters, BASE is offset of the counter position. */
515 void
516 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
518 gimple stmt = value->hvalue.stmt;
519 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
520 tree ref_ptr = tree_coverage_counter_addr (tag, base);
521 gimple call;
522 tree val;
524 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
525 true, NULL_TREE,
526 true, GSI_SAME_STMT);
527 val = prepare_instrumented_value (&gsi, value);
528 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
529 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
532 /* Output instructions as GIMPLE trees to increment the ior histogram
533 counter. VALUE is the expression whose value is profiled. TAG is the
534 tag of the section for counters, BASE is offset of the counter position. */
536 void
537 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
539 gimple stmt = value->hvalue.stmt;
540 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
541 tree ref_ptr = tree_coverage_counter_addr (tag, base);
542 gimple call;
543 tree val;
545 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
546 true, NULL_TREE, true, GSI_SAME_STMT);
547 val = prepare_instrumented_value (&gsi, value);
548 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
549 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
552 /* Profile all functions in the callgraph. */
554 static unsigned int
555 tree_profiling (void)
557 struct cgraph_node *node;
559 /* This is a small-ipa pass that gets called only once, from
560 cgraphunit.c:ipa_passes(). */
561 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
563 init_node_map (true);
565 FOR_EACH_DEFINED_FUNCTION (node)
567 if (!gimple_has_body_p (node->decl))
568 continue;
570 /* Don't profile functions produced for builtin stuff. */
571 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
572 continue;
574 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
576 /* Local pure-const may imply need to fixup the cfg. */
577 if (execute_fixup_cfg () & TODO_cleanup_cfg)
578 cleanup_tree_cfg ();
580 branch_prob ();
582 if (! flag_branch_probabilities
583 && flag_profile_values)
584 gimple_gen_ic_func_profiler ();
586 if (flag_branch_probabilities
587 && flag_profile_values
588 && flag_value_profile_transformations)
589 gimple_value_profile_transformations ();
591 /* The above could hose dominator info. Currently there is
592 none coming in, this is a safety valve. It should be
593 easy to adjust it, if and when there is some. */
594 free_dominance_info (CDI_DOMINATORS);
595 free_dominance_info (CDI_POST_DOMINATORS);
596 pop_cfun ();
599 /* Drop pure/const flags from instrumented functions. */
600 FOR_EACH_DEFINED_FUNCTION (node)
602 if (!gimple_has_body_p (node->decl)
603 || !(!node->clone_of
604 || node->decl != node->clone_of->decl))
605 continue;
607 /* Don't profile functions produced for builtin stuff. */
608 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
609 continue;
611 cgraph_set_const_flag (node, false, false);
612 cgraph_set_pure_flag (node, false, false);
615 /* Update call statements and rebuild the cgraph. */
616 FOR_EACH_DEFINED_FUNCTION (node)
618 basic_block bb;
620 if (!gimple_has_body_p (node->decl)
621 || !(!node->clone_of
622 || node->decl != node->clone_of->decl))
623 continue;
625 /* Don't profile functions produced for builtin stuff. */
626 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
627 continue;
629 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
631 FOR_EACH_BB (bb)
633 gimple_stmt_iterator gsi;
634 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
636 gimple stmt = gsi_stmt (gsi);
637 if (is_gimple_call (stmt))
638 update_stmt (stmt);
642 /* re-merge split blocks. */
643 cleanup_tree_cfg ();
644 update_ssa (TODO_update_ssa);
646 rebuild_cgraph_edges ();
648 pop_cfun ();
651 handle_missing_profiles ();
653 del_node_map ();
654 return 0;
657 /* When profile instrumentation, use or test coverage shall be performed. */
659 static bool
660 gate_tree_profile_ipa (void)
662 return (!in_lto_p
663 && (flag_branch_probabilities || flag_test_coverage
664 || profile_arc_flag));
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 true, /* has_gate */
675 true, /* has_execute */
676 TV_IPA_PROFILE, /* tv_id */
677 0, /* properties_required */
678 0, /* properties_provided */
679 0, /* properties_destroyed */
680 0, /* todo_flags_start */
681 0, /* todo_flags_finish */
684 class pass_ipa_tree_profile : public simple_ipa_opt_pass
686 public:
687 pass_ipa_tree_profile (gcc::context *ctxt)
688 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
691 /* opt_pass methods: */
692 bool gate () { return gate_tree_profile_ipa (); }
693 unsigned int execute () { return tree_profiling (); }
695 }; // class pass_ipa_tree_profile
697 } // anon namespace
699 simple_ipa_opt_pass *
700 make_pass_ipa_tree_profile (gcc::context *ctxt)
702 return new pass_ipa_tree_profile (ctxt);
705 #include "gt-tree-profile.h"