2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / tree-profile.c
blob0adc51a51aa960bd74b684a3f0255c943db02b42
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 "varasm.h"
39 #include "tree-nested.h"
40 #include "gimplify.h"
41 #include "gimple-iterator.h"
42 #include "gimplify-me.h"
43 #include "gimple-ssa.h"
44 #include "cgraph.h"
45 #include "tree-cfg.h"
46 #include "stringpool.h"
47 #include "tree-ssanames.h"
48 #include "tree-into-ssa.h"
49 #include "tree-pass.h"
50 #include "value-prof.h"
51 #include "profile.h"
52 #include "target.h"
53 #include "tree-cfgcleanup.h"
54 #include "tree-nested.h"
56 static GTY(()) tree gcov_type_node;
57 static GTY(()) tree tree_interval_profiler_fn;
58 static GTY(()) tree tree_pow2_profiler_fn;
59 static GTY(()) tree tree_one_value_profiler_fn;
60 static GTY(()) tree tree_indirect_call_profiler_fn;
61 static GTY(()) tree tree_time_profiler_fn;
62 static GTY(()) tree tree_average_profiler_fn;
63 static GTY(()) tree tree_ior_profiler_fn;
66 static GTY(()) tree ic_void_ptr_var;
67 static GTY(()) tree ic_gcov_type_ptr_var;
68 static GTY(()) tree ptr_void;
70 /* Do initialization work for the edge profiler. */
72 /* Add code:
73 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
74 __thread void* __gcov_indirect_call_callee; // actual callee address
75 __thread int __gcov_function_counter; // time profiler function counter
77 static void
78 init_ic_make_global_vars (void)
80 tree gcov_type_ptr;
82 ptr_void = build_pointer_type (void_type_node);
84 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
85 if (flag_lto)
87 ic_void_ptr_var
88 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
89 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
90 ptr_void);
91 TREE_PUBLIC (ic_void_ptr_var) = 1;
92 DECL_COMMON (ic_void_ptr_var) = 1;
93 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
94 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
96 else
98 ic_void_ptr_var
99 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
100 get_identifier ("__gcov_indirect_call_callee"),
101 ptr_void);
102 TREE_PUBLIC (ic_void_ptr_var) = 1;
103 DECL_EXTERNAL (ic_void_ptr_var) = 1;
105 TREE_STATIC (ic_void_ptr_var) = 1;
106 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
107 DECL_INITIAL (ic_void_ptr_var) = NULL;
108 if (targetm.have_tls)
109 DECL_TLS_MODEL (ic_void_ptr_var) =
110 decl_default_tls_model (ic_void_ptr_var);
112 varpool_finalize_decl (ic_void_ptr_var);
114 gcov_type_ptr = build_pointer_type (get_gcov_type ());
115 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
116 if (flag_lto)
118 ic_gcov_type_ptr_var
119 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
120 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
121 gcov_type_ptr);
122 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
123 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
124 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
125 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
127 else
129 ic_gcov_type_ptr_var
130 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
131 get_identifier ("__gcov_indirect_call_counters"),
132 gcov_type_ptr);
133 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
134 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
136 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
137 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
138 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
139 if (targetm.have_tls)
140 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
141 decl_default_tls_model (ic_gcov_type_ptr_var);
143 varpool_finalize_decl (ic_gcov_type_ptr_var);
146 /* Create the type and function decls for the interface with gcov. */
148 void
149 gimple_init_edge_profiler (void)
151 tree interval_profiler_fn_type;
152 tree pow2_profiler_fn_type;
153 tree one_value_profiler_fn_type;
154 tree gcov_type_ptr;
155 tree ic_profiler_fn_type;
156 tree average_profiler_fn_type;
157 tree time_profiler_fn_type;
159 if (!gcov_type_node)
161 gcov_type_node = get_gcov_type ();
162 gcov_type_ptr = build_pointer_type (gcov_type_node);
164 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
165 interval_profiler_fn_type
166 = build_function_type_list (void_type_node,
167 gcov_type_ptr, gcov_type_node,
168 integer_type_node,
169 unsigned_type_node, NULL_TREE);
170 tree_interval_profiler_fn
171 = build_fn_decl ("__gcov_interval_profiler",
172 interval_profiler_fn_type);
173 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
174 DECL_ATTRIBUTES (tree_interval_profiler_fn)
175 = tree_cons (get_identifier ("leaf"), NULL,
176 DECL_ATTRIBUTES (tree_interval_profiler_fn));
178 /* void (*) (gcov_type *, gcov_type) */
179 pow2_profiler_fn_type
180 = build_function_type_list (void_type_node,
181 gcov_type_ptr, gcov_type_node,
182 NULL_TREE);
183 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
184 pow2_profiler_fn_type);
185 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
186 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
187 = tree_cons (get_identifier ("leaf"), NULL,
188 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
190 /* void (*) (gcov_type *, gcov_type) */
191 one_value_profiler_fn_type
192 = build_function_type_list (void_type_node,
193 gcov_type_ptr, gcov_type_node,
194 NULL_TREE);
195 tree_one_value_profiler_fn
196 = build_fn_decl ("__gcov_one_value_profiler",
197 one_value_profiler_fn_type);
198 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
199 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
200 = tree_cons (get_identifier ("leaf"), NULL,
201 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
203 init_ic_make_global_vars ();
205 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
206 if (flag_lto)
208 /* void (*) (gcov_type, void *) */
209 ic_profiler_fn_type
210 = build_function_type_list (void_type_node,
211 gcov_type_ptr, gcov_type_node,
212 ptr_void, ptr_void,
213 NULL_TREE);
214 tree_indirect_call_profiler_fn
215 = build_fn_decl ("__gcov_indirect_call_profiler",
216 ic_profiler_fn_type);
218 else
220 /* void (*) (gcov_type, void *) */
221 ic_profiler_fn_type
222 = build_function_type_list (void_type_node,
223 gcov_type_node,
224 ptr_void,
225 NULL_TREE);
226 tree_indirect_call_profiler_fn
227 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
228 ic_profiler_fn_type);
230 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
231 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
232 = tree_cons (get_identifier ("leaf"), NULL,
233 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
235 /* void (*) (gcov_type *, gcov_type, void *) */
236 time_profiler_fn_type
237 = build_function_type_list (void_type_node,
238 gcov_type_ptr, NULL_TREE);
239 tree_time_profiler_fn
240 = build_fn_decl ("__gcov_time_profiler",
241 time_profiler_fn_type);
242 TREE_NOTHROW (tree_time_profiler_fn) = 1;
243 DECL_ATTRIBUTES (tree_time_profiler_fn)
244 = tree_cons (get_identifier ("leaf"), NULL,
245 DECL_ATTRIBUTES (tree_time_profiler_fn));
247 /* void (*) (gcov_type *, gcov_type) */
248 average_profiler_fn_type
249 = build_function_type_list (void_type_node,
250 gcov_type_ptr, gcov_type_node, NULL_TREE);
251 tree_average_profiler_fn
252 = build_fn_decl ("__gcov_average_profiler",
253 average_profiler_fn_type);
254 TREE_NOTHROW (tree_average_profiler_fn) = 1;
255 DECL_ATTRIBUTES (tree_average_profiler_fn)
256 = tree_cons (get_identifier ("leaf"), NULL,
257 DECL_ATTRIBUTES (tree_average_profiler_fn));
258 tree_ior_profiler_fn
259 = build_fn_decl ("__gcov_ior_profiler",
260 average_profiler_fn_type);
261 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
262 DECL_ATTRIBUTES (tree_ior_profiler_fn)
263 = tree_cons (get_identifier ("leaf"), NULL,
264 DECL_ATTRIBUTES (tree_ior_profiler_fn));
266 /* LTO streamer needs assembler names. Because we create these decls
267 late, we need to initialize them by hand. */
268 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
269 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
270 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
271 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
272 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
273 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
274 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
278 /* Output instructions as GIMPLE trees to increment the edge
279 execution count, and insert them on E. We rely on
280 gsi_insert_on_edge to preserve the order. */
282 void
283 gimple_gen_edge_profiler (int edgeno, edge e)
285 tree ref, one, gcov_type_tmp_var;
286 gimple stmt1, stmt2, stmt3;
288 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
289 one = build_int_cst (gcov_type_node, 1);
290 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
291 NULL, "PROF_edge_counter");
292 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
293 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
294 NULL, "PROF_edge_counter");
295 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
296 gimple_assign_lhs (stmt1), one);
297 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
298 gsi_insert_on_edge (e, stmt1);
299 gsi_insert_on_edge (e, stmt2);
300 gsi_insert_on_edge (e, stmt3);
303 /* Emits code to get VALUE to instrument at GSI, and returns the
304 variable containing the value. */
306 static tree
307 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
309 tree val = value->hvalue.value;
310 if (POINTER_TYPE_P (TREE_TYPE (val)))
311 val = fold_convert (build_nonstandard_integer_type
312 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
313 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
314 true, NULL_TREE, true, GSI_SAME_STMT);
317 /* Output instructions as GIMPLE trees to increment the interval histogram
318 counter. VALUE is the expression whose value is profiled. TAG is the
319 tag of the section for counters, BASE is offset of the counter position. */
321 void
322 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
324 gimple stmt = value->hvalue.stmt;
325 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
326 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
327 gimple call;
328 tree val;
329 tree start = build_int_cst_type (integer_type_node,
330 value->hdata.intvl.int_start);
331 tree steps = build_int_cst_type (unsigned_type_node,
332 value->hdata.intvl.steps);
334 ref_ptr = force_gimple_operand_gsi (&gsi,
335 build_addr (ref, current_function_decl),
336 true, NULL_TREE, true, GSI_SAME_STMT);
337 val = prepare_instrumented_value (&gsi, value);
338 call = gimple_build_call (tree_interval_profiler_fn, 4,
339 ref_ptr, val, start, steps);
340 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
343 /* Output instructions as GIMPLE trees to increment the power of two histogram
344 counter. VALUE is the expression whose value is profiled. TAG is the tag
345 of the section for counters, BASE is offset of the counter position. */
347 void
348 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
350 gimple stmt = value->hvalue.stmt;
351 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
352 tree ref_ptr = tree_coverage_counter_addr (tag, base);
353 gimple call;
354 tree val;
356 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
357 true, NULL_TREE, true, GSI_SAME_STMT);
358 val = prepare_instrumented_value (&gsi, value);
359 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
360 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
363 /* Output instructions as GIMPLE trees for code to find the most common value.
364 VALUE is the expression whose value is profiled. TAG is the tag of the
365 section for counters, BASE is offset of the counter position. */
367 void
368 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
370 gimple stmt = value->hvalue.stmt;
371 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
372 tree ref_ptr = tree_coverage_counter_addr (tag, base);
373 gimple call;
374 tree val;
376 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
377 true, NULL_TREE, true, GSI_SAME_STMT);
378 val = prepare_instrumented_value (&gsi, value);
379 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
380 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
384 /* Output instructions as GIMPLE trees for code to find the most
385 common called function in indirect call.
386 VALUE is the call expression whose indirect callee is profiled.
387 TAG is the tag of the section for counters, BASE is offset of the
388 counter position. */
390 void
391 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
393 tree tmp1;
394 gimple stmt1, stmt2, stmt3;
395 gimple stmt = value->hvalue.stmt;
396 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
397 tree ref_ptr = tree_coverage_counter_addr (tag, base);
399 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
400 true, NULL_TREE, true, GSI_SAME_STMT);
402 /* Insert code:
404 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
405 stmt2: tmp1 = (void *) (indirect call argument value)
406 stmt3: __gcov_indirect_call_callee = tmp1;
409 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
410 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
411 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
412 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
414 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
415 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
416 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
420 /* Output instructions as GIMPLE trees for code to find the most
421 common called function in indirect call. Insert instructions at the
422 beginning of every possible called function.
425 void
426 gimple_gen_ic_func_profiler (void)
428 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
429 gimple_stmt_iterator gsi;
430 gimple stmt1, stmt2;
431 tree tree_uid, cur_func, void0;
433 if (cgraph_only_called_directly_p (c_node))
434 return;
436 gimple_init_edge_profiler ();
438 /* Insert code:
440 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
441 &current_function_decl)
443 gsi =
444 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
446 cur_func = force_gimple_operand_gsi (&gsi,
447 build_addr (current_function_decl,
448 current_function_decl),
449 true, NULL_TREE,
450 true, GSI_SAME_STMT);
451 tree_uid = build_int_cst
452 (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
453 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
454 if (flag_lto)
456 tree counter_ptr, ptr_var;
457 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
458 true, NULL_TREE, true,
459 GSI_SAME_STMT);
460 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
461 true, NULL_TREE, true,
462 GSI_SAME_STMT);
464 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
465 counter_ptr, tree_uid, cur_func, ptr_var);
467 else
469 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
470 tree_uid, cur_func);
472 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
474 /* Set __gcov_indirect_call_callee to 0,
475 so that calls from other modules won't get misattributed
476 to the last caller of the current callee. */
477 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
478 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
479 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
482 /* Output instructions as GIMPLE tree at the beginning for each function.
483 TAG is the tag of the section for counters, BASE is offset of the
484 counter position and GSI is the iterator we place the counter. */
486 void
487 gimple_gen_time_profiler (unsigned tag, unsigned base,
488 gimple_stmt_iterator &gsi)
490 tree ref_ptr = tree_coverage_counter_addr (tag, base);
491 gimple call;
493 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
494 true, NULL_TREE, true, GSI_SAME_STMT);
495 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
496 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
499 /* Output instructions as GIMPLE trees for code to find the most common value
500 of a difference between two evaluations of an expression.
501 VALUE is the expression whose value is profiled. TAG is the tag of the
502 section for counters, BASE is offset of the counter position. */
504 void
505 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
506 unsigned tag ATTRIBUTE_UNUSED,
507 unsigned base ATTRIBUTE_UNUSED)
509 /* FIXME implement this. */
510 #ifdef ENABLE_CHECKING
511 internal_error ("unimplemented functionality");
512 #endif
513 gcc_unreachable ();
516 /* Output instructions as GIMPLE trees to increment the average histogram
517 counter. VALUE is the expression whose value is profiled. TAG is the
518 tag of the section for counters, BASE is offset of the counter position. */
520 void
521 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
523 gimple stmt = value->hvalue.stmt;
524 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
525 tree ref_ptr = tree_coverage_counter_addr (tag, base);
526 gimple call;
527 tree val;
529 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
530 true, NULL_TREE,
531 true, GSI_SAME_STMT);
532 val = prepare_instrumented_value (&gsi, value);
533 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
534 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
537 /* Output instructions as GIMPLE trees to increment the ior histogram
538 counter. VALUE is the expression whose value is profiled. TAG is the
539 tag of the section for counters, BASE is offset of the counter position. */
541 void
542 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
544 gimple stmt = value->hvalue.stmt;
545 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
546 tree ref_ptr = tree_coverage_counter_addr (tag, base);
547 gimple call;
548 tree val;
550 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
551 true, NULL_TREE, true, GSI_SAME_STMT);
552 val = prepare_instrumented_value (&gsi, value);
553 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
554 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
557 /* Profile all functions in the callgraph. */
559 static unsigned int
560 tree_profiling (void)
562 struct cgraph_node *node;
564 /* This is a small-ipa pass that gets called only once, from
565 cgraphunit.c:ipa_passes(). */
566 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
568 init_node_map (true);
570 FOR_EACH_DEFINED_FUNCTION (node)
572 if (!gimple_has_body_p (node->decl))
573 continue;
575 /* Don't profile functions produced for builtin stuff. */
576 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
577 continue;
579 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
581 /* Local pure-const may imply need to fixup the cfg. */
582 if (execute_fixup_cfg () & TODO_cleanup_cfg)
583 cleanup_tree_cfg ();
585 branch_prob ();
587 if (! flag_branch_probabilities
588 && flag_profile_values)
589 gimple_gen_ic_func_profiler ();
591 if (flag_branch_probabilities
592 && flag_profile_values
593 && flag_value_profile_transformations)
594 gimple_value_profile_transformations ();
596 /* The above could hose dominator info. Currently there is
597 none coming in, this is a safety valve. It should be
598 easy to adjust it, if and when there is some. */
599 free_dominance_info (CDI_DOMINATORS);
600 free_dominance_info (CDI_POST_DOMINATORS);
601 pop_cfun ();
604 /* Drop pure/const flags from instrumented functions. */
605 FOR_EACH_DEFINED_FUNCTION (node)
607 if (!gimple_has_body_p (node->decl)
608 || !(!node->clone_of
609 || node->decl != node->clone_of->decl))
610 continue;
612 /* Don't profile functions produced for builtin stuff. */
613 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
614 continue;
616 cgraph_set_const_flag (node, false, false);
617 cgraph_set_pure_flag (node, false, false);
620 /* Update call statements and rebuild the cgraph. */
621 FOR_EACH_DEFINED_FUNCTION (node)
623 basic_block bb;
625 if (!gimple_has_body_p (node->decl)
626 || !(!node->clone_of
627 || node->decl != node->clone_of->decl))
628 continue;
630 /* Don't profile functions produced for builtin stuff. */
631 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
632 continue;
634 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
636 FOR_EACH_BB (bb)
638 gimple_stmt_iterator gsi;
639 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
641 gimple stmt = gsi_stmt (gsi);
642 if (is_gimple_call (stmt))
643 update_stmt (stmt);
647 /* re-merge split blocks. */
648 cleanup_tree_cfg ();
649 update_ssa (TODO_update_ssa);
651 rebuild_cgraph_edges ();
653 pop_cfun ();
656 handle_missing_profiles ();
658 del_node_map ();
659 return 0;
662 /* When profile instrumentation, use or test coverage shall be performed. */
664 static bool
665 gate_tree_profile_ipa (void)
667 return (!in_lto_p
668 && (flag_branch_probabilities || flag_test_coverage
669 || profile_arc_flag));
672 namespace {
674 const pass_data pass_data_ipa_tree_profile =
676 SIMPLE_IPA_PASS, /* type */
677 "profile", /* name */
678 OPTGROUP_NONE, /* optinfo_flags */
679 true, /* has_gate */
680 true, /* has_execute */
681 TV_IPA_PROFILE, /* tv_id */
682 0, /* properties_required */
683 0, /* properties_provided */
684 0, /* properties_destroyed */
685 0, /* todo_flags_start */
686 0, /* todo_flags_finish */
689 class pass_ipa_tree_profile : public simple_ipa_opt_pass
691 public:
692 pass_ipa_tree_profile (gcc::context *ctxt)
693 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
696 /* opt_pass methods: */
697 bool gate () { return gate_tree_profile_ipa (); }
698 unsigned int execute () { return tree_profiling (); }
700 }; // class pass_ipa_tree_profile
702 } // anon namespace
704 simple_ipa_opt_pass *
705 make_pass_ipa_tree_profile (gcc::context *ctxt)
707 return new pass_ipa_tree_profile (ctxt);
710 #include "gt-tree-profile.h"