[ARM 2/5 big.LITTLE] Allow tuning parameters without unique tuning targets.
[official-gcc.git] / gcc / tree-profile.c
blob51e997ccd4faf38d45f204289649f16bef2ca784
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 "tree-ssa-alias.h"
38 #include "internal-fn.h"
39 #include "gimple-expr.h"
40 #include "is-a.h"
41 #include "gimple.h"
42 #include "varasm.h"
43 #include "tree-nested.h"
44 #include "gimplify.h"
45 #include "gimple-iterator.h"
46 #include "gimplify-me.h"
47 #include "gimple-ssa.h"
48 #include "cgraph.h"
49 #include "tree-cfg.h"
50 #include "stringpool.h"
51 #include "tree-ssanames.h"
52 #include "tree-into-ssa.h"
53 #include "tree-pass.h"
54 #include "value-prof.h"
55 #include "profile.h"
56 #include "target.h"
57 #include "tree-cfgcleanup.h"
58 #include "tree-nested.h"
60 static GTY(()) tree gcov_type_node;
61 static GTY(()) tree tree_interval_profiler_fn;
62 static GTY(()) tree tree_pow2_profiler_fn;
63 static GTY(()) tree tree_one_value_profiler_fn;
64 static GTY(()) tree tree_indirect_call_profiler_fn;
65 static GTY(()) tree tree_time_profiler_fn;
66 static GTY(()) tree tree_average_profiler_fn;
67 static GTY(()) tree tree_ior_profiler_fn;
70 static GTY(()) tree ic_void_ptr_var;
71 static GTY(()) tree ic_gcov_type_ptr_var;
72 static GTY(()) tree ptr_void;
74 /* Do initialization work for the edge profiler. */
76 /* Add code:
77 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
78 __thread void* __gcov_indirect_call_callee; // actual callee address
79 __thread int __gcov_function_counter; // time profiler function counter
81 static void
82 init_ic_make_global_vars (void)
84 tree gcov_type_ptr;
86 ptr_void = build_pointer_type (void_type_node);
88 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
89 if (flag_lto)
91 ic_void_ptr_var
92 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
93 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
94 ptr_void);
95 TREE_PUBLIC (ic_void_ptr_var) = 1;
96 DECL_COMMON (ic_void_ptr_var) = 1;
97 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
98 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
100 else
102 ic_void_ptr_var
103 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
104 get_identifier ("__gcov_indirect_call_callee"),
105 ptr_void);
106 TREE_PUBLIC (ic_void_ptr_var) = 1;
107 DECL_EXTERNAL (ic_void_ptr_var) = 1;
109 TREE_STATIC (ic_void_ptr_var) = 1;
110 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
111 DECL_INITIAL (ic_void_ptr_var) = NULL;
112 if (targetm.have_tls)
113 DECL_TLS_MODEL (ic_void_ptr_var) =
114 decl_default_tls_model (ic_void_ptr_var);
116 varpool_finalize_decl (ic_void_ptr_var);
118 gcov_type_ptr = build_pointer_type (get_gcov_type ());
119 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
120 if (flag_lto)
122 ic_gcov_type_ptr_var
123 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
124 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
125 gcov_type_ptr);
126 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
127 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
128 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
129 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
131 else
133 ic_gcov_type_ptr_var
134 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
135 get_identifier ("__gcov_indirect_call_counters"),
136 gcov_type_ptr);
137 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
138 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
140 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
141 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
142 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
143 if (targetm.have_tls)
144 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
145 decl_default_tls_model (ic_gcov_type_ptr_var);
147 varpool_finalize_decl (ic_gcov_type_ptr_var);
150 /* Create the type and function decls for the interface with gcov. */
152 void
153 gimple_init_edge_profiler (void)
155 tree interval_profiler_fn_type;
156 tree pow2_profiler_fn_type;
157 tree one_value_profiler_fn_type;
158 tree gcov_type_ptr;
159 tree ic_profiler_fn_type;
160 tree average_profiler_fn_type;
161 tree time_profiler_fn_type;
163 if (!gcov_type_node)
165 gcov_type_node = get_gcov_type ();
166 gcov_type_ptr = build_pointer_type (gcov_type_node);
168 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
169 interval_profiler_fn_type
170 = build_function_type_list (void_type_node,
171 gcov_type_ptr, gcov_type_node,
172 integer_type_node,
173 unsigned_type_node, NULL_TREE);
174 tree_interval_profiler_fn
175 = build_fn_decl ("__gcov_interval_profiler",
176 interval_profiler_fn_type);
177 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
178 DECL_ATTRIBUTES (tree_interval_profiler_fn)
179 = tree_cons (get_identifier ("leaf"), NULL,
180 DECL_ATTRIBUTES (tree_interval_profiler_fn));
182 /* void (*) (gcov_type *, gcov_type) */
183 pow2_profiler_fn_type
184 = build_function_type_list (void_type_node,
185 gcov_type_ptr, gcov_type_node,
186 NULL_TREE);
187 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
188 pow2_profiler_fn_type);
189 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
190 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
191 = tree_cons (get_identifier ("leaf"), NULL,
192 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
194 /* void (*) (gcov_type *, gcov_type) */
195 one_value_profiler_fn_type
196 = build_function_type_list (void_type_node,
197 gcov_type_ptr, gcov_type_node,
198 NULL_TREE);
199 tree_one_value_profiler_fn
200 = build_fn_decl ("__gcov_one_value_profiler",
201 one_value_profiler_fn_type);
202 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
203 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
204 = tree_cons (get_identifier ("leaf"), NULL,
205 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
207 init_ic_make_global_vars ();
209 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
210 if (flag_lto)
212 /* void (*) (gcov_type, void *) */
213 ic_profiler_fn_type
214 = build_function_type_list (void_type_node,
215 gcov_type_ptr, gcov_type_node,
216 ptr_void, ptr_void,
217 NULL_TREE);
218 tree_indirect_call_profiler_fn
219 = build_fn_decl ("__gcov_indirect_call_profiler",
220 ic_profiler_fn_type);
222 else
224 /* void (*) (gcov_type, void *) */
225 ic_profiler_fn_type
226 = build_function_type_list (void_type_node,
227 gcov_type_node,
228 ptr_void,
229 NULL_TREE);
230 tree_indirect_call_profiler_fn
231 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
232 ic_profiler_fn_type);
234 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
235 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
236 = tree_cons (get_identifier ("leaf"), NULL,
237 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
239 /* void (*) (gcov_type *, gcov_type, void *) */
240 time_profiler_fn_type
241 = build_function_type_list (void_type_node,
242 gcov_type_ptr, NULL_TREE);
243 tree_time_profiler_fn
244 = build_fn_decl ("__gcov_time_profiler",
245 time_profiler_fn_type);
246 TREE_NOTHROW (tree_time_profiler_fn) = 1;
247 DECL_ATTRIBUTES (tree_time_profiler_fn)
248 = tree_cons (get_identifier ("leaf"), NULL,
249 DECL_ATTRIBUTES (tree_time_profiler_fn));
251 /* void (*) (gcov_type *, gcov_type) */
252 average_profiler_fn_type
253 = build_function_type_list (void_type_node,
254 gcov_type_ptr, gcov_type_node, NULL_TREE);
255 tree_average_profiler_fn
256 = build_fn_decl ("__gcov_average_profiler",
257 average_profiler_fn_type);
258 TREE_NOTHROW (tree_average_profiler_fn) = 1;
259 DECL_ATTRIBUTES (tree_average_profiler_fn)
260 = tree_cons (get_identifier ("leaf"), NULL,
261 DECL_ATTRIBUTES (tree_average_profiler_fn));
262 tree_ior_profiler_fn
263 = build_fn_decl ("__gcov_ior_profiler",
264 average_profiler_fn_type);
265 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
266 DECL_ATTRIBUTES (tree_ior_profiler_fn)
267 = tree_cons (get_identifier ("leaf"), NULL,
268 DECL_ATTRIBUTES (tree_ior_profiler_fn));
270 /* LTO streamer needs assembler names. Because we create these decls
271 late, we need to initialize them by hand. */
272 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
273 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
274 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
275 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
276 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
277 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
278 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
282 /* Output instructions as GIMPLE trees to increment the edge
283 execution count, and insert them on E. We rely on
284 gsi_insert_on_edge to preserve the order. */
286 void
287 gimple_gen_edge_profiler (int edgeno, edge e)
289 tree ref, one, gcov_type_tmp_var;
290 gimple stmt1, stmt2, stmt3;
292 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
293 one = build_int_cst (gcov_type_node, 1);
294 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
295 NULL, "PROF_edge_counter");
296 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
297 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
298 NULL, "PROF_edge_counter");
299 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
300 gimple_assign_lhs (stmt1), one);
301 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
302 gsi_insert_on_edge (e, stmt1);
303 gsi_insert_on_edge (e, stmt2);
304 gsi_insert_on_edge (e, stmt3);
307 /* Emits code to get VALUE to instrument at GSI, and returns the
308 variable containing the value. */
310 static tree
311 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
313 tree val = value->hvalue.value;
314 if (POINTER_TYPE_P (TREE_TYPE (val)))
315 val = fold_convert (build_nonstandard_integer_type
316 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
317 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
318 true, NULL_TREE, true, GSI_SAME_STMT);
321 /* Output instructions as GIMPLE trees to increment the interval histogram
322 counter. VALUE is the expression whose value is profiled. TAG is the
323 tag of the section for counters, BASE is offset of the counter position. */
325 void
326 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
328 gimple stmt = value->hvalue.stmt;
329 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
330 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
331 gimple call;
332 tree val;
333 tree start = build_int_cst_type (integer_type_node,
334 value->hdata.intvl.int_start);
335 tree steps = build_int_cst_type (unsigned_type_node,
336 value->hdata.intvl.steps);
338 ref_ptr = force_gimple_operand_gsi (&gsi,
339 build_addr (ref, current_function_decl),
340 true, NULL_TREE, true, GSI_SAME_STMT);
341 val = prepare_instrumented_value (&gsi, value);
342 call = gimple_build_call (tree_interval_profiler_fn, 4,
343 ref_ptr, val, start, steps);
344 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
347 /* Output instructions as GIMPLE trees to increment the power of two histogram
348 counter. VALUE is the expression whose value is profiled. TAG is the tag
349 of the section for counters, BASE is offset of the counter position. */
351 void
352 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
354 gimple stmt = value->hvalue.stmt;
355 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
356 tree ref_ptr = tree_coverage_counter_addr (tag, base);
357 gimple call;
358 tree val;
360 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
361 true, NULL_TREE, true, GSI_SAME_STMT);
362 val = prepare_instrumented_value (&gsi, value);
363 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
364 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
367 /* Output instructions as GIMPLE trees for code to find the most common value.
368 VALUE is the expression whose value is profiled. TAG is the tag of the
369 section for counters, BASE is offset of the counter position. */
371 void
372 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
374 gimple stmt = value->hvalue.stmt;
375 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
376 tree ref_ptr = tree_coverage_counter_addr (tag, base);
377 gimple call;
378 tree val;
380 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
381 true, NULL_TREE, true, GSI_SAME_STMT);
382 val = prepare_instrumented_value (&gsi, value);
383 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
384 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
388 /* Output instructions as GIMPLE trees for code to find the most
389 common called function in indirect call.
390 VALUE is the call expression whose indirect callee is profiled.
391 TAG is the tag of the section for counters, BASE is offset of the
392 counter position. */
394 void
395 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
397 tree tmp1;
398 gimple stmt1, stmt2, stmt3;
399 gimple stmt = value->hvalue.stmt;
400 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
401 tree ref_ptr = tree_coverage_counter_addr (tag, base);
403 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
404 true, NULL_TREE, true, GSI_SAME_STMT);
406 /* Insert code:
408 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
409 stmt2: tmp1 = (void *) (indirect call argument value)
410 stmt3: __gcov_indirect_call_callee = tmp1;
413 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
414 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
415 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
416 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
418 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
419 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
420 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
424 /* Output instructions as GIMPLE trees for code to find the most
425 common called function in indirect call. Insert instructions at the
426 beginning of every possible called function.
429 void
430 gimple_gen_ic_func_profiler (void)
432 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
433 gimple_stmt_iterator gsi;
434 gimple stmt1, stmt2;
435 tree tree_uid, cur_func, void0;
437 if (cgraph_only_called_directly_p (c_node))
438 return;
440 gimple_init_edge_profiler ();
442 /* Insert code:
444 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
445 &current_function_decl)
447 gsi =
448 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
450 cur_func = force_gimple_operand_gsi (&gsi,
451 build_addr (current_function_decl,
452 current_function_decl),
453 true, NULL_TREE,
454 true, GSI_SAME_STMT);
455 tree_uid = build_int_cst
456 (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
457 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
458 if (flag_lto)
460 tree counter_ptr, ptr_var;
461 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
462 true, NULL_TREE, true,
463 GSI_SAME_STMT);
464 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
465 true, NULL_TREE, true,
466 GSI_SAME_STMT);
468 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
469 counter_ptr, tree_uid, cur_func, ptr_var);
471 else
473 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
474 tree_uid, cur_func);
476 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
478 /* Set __gcov_indirect_call_callee to 0,
479 so that calls from other modules won't get misattributed
480 to the last caller of the current callee. */
481 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
482 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
483 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
486 /* Output instructions as GIMPLE tree at the beginning for each function.
487 TAG is the tag of the section for counters, BASE is offset of the
488 counter position and GSI is the iterator we place the counter. */
490 void
491 gimple_gen_time_profiler (unsigned tag, unsigned base,
492 gimple_stmt_iterator &gsi)
494 tree ref_ptr = tree_coverage_counter_addr (tag, base);
495 gimple call;
497 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
498 true, NULL_TREE, true, GSI_SAME_STMT);
499 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
500 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
503 /* Output instructions as GIMPLE trees for code to find the most common value
504 of a difference between two evaluations of an expression.
505 VALUE is the expression whose value is profiled. TAG is the tag of the
506 section for counters, BASE is offset of the counter position. */
508 void
509 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
510 unsigned tag ATTRIBUTE_UNUSED,
511 unsigned base ATTRIBUTE_UNUSED)
513 /* FIXME implement this. */
514 #ifdef ENABLE_CHECKING
515 internal_error ("unimplemented functionality");
516 #endif
517 gcc_unreachable ();
520 /* Output instructions as GIMPLE trees to increment the average histogram
521 counter. VALUE is the expression whose value is profiled. TAG is the
522 tag of the section for counters, BASE is offset of the counter position. */
524 void
525 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
527 gimple stmt = value->hvalue.stmt;
528 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
529 tree ref_ptr = tree_coverage_counter_addr (tag, base);
530 gimple call;
531 tree val;
533 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
534 true, NULL_TREE,
535 true, GSI_SAME_STMT);
536 val = prepare_instrumented_value (&gsi, value);
537 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
538 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
541 /* Output instructions as GIMPLE trees to increment the ior histogram
542 counter. VALUE is the expression whose value is profiled. TAG is the
543 tag of the section for counters, BASE is offset of the counter position. */
545 void
546 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
548 gimple stmt = value->hvalue.stmt;
549 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
550 tree ref_ptr = tree_coverage_counter_addr (tag, base);
551 gimple call;
552 tree val;
554 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
555 true, NULL_TREE, true, GSI_SAME_STMT);
556 val = prepare_instrumented_value (&gsi, value);
557 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
558 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
561 /* Profile all functions in the callgraph. */
563 static unsigned int
564 tree_profiling (void)
566 struct cgraph_node *node;
568 /* This is a small-ipa pass that gets called only once, from
569 cgraphunit.c:ipa_passes(). */
570 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
572 init_node_map (true);
574 FOR_EACH_DEFINED_FUNCTION (node)
576 if (!gimple_has_body_p (node->decl))
577 continue;
579 /* Don't profile functions produced for builtin stuff. */
580 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
581 continue;
583 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
585 /* Local pure-const may imply need to fixup the cfg. */
586 if (execute_fixup_cfg () & TODO_cleanup_cfg)
587 cleanup_tree_cfg ();
589 branch_prob ();
591 if (! flag_branch_probabilities
592 && flag_profile_values)
593 gimple_gen_ic_func_profiler ();
595 if (flag_branch_probabilities
596 && flag_profile_values
597 && flag_value_profile_transformations)
598 gimple_value_profile_transformations ();
600 /* The above could hose dominator info. Currently there is
601 none coming in, this is a safety valve. It should be
602 easy to adjust it, if and when there is some. */
603 free_dominance_info (CDI_DOMINATORS);
604 free_dominance_info (CDI_POST_DOMINATORS);
605 pop_cfun ();
608 /* Drop pure/const flags from instrumented functions. */
609 FOR_EACH_DEFINED_FUNCTION (node)
611 if (!gimple_has_body_p (node->decl)
612 || !(!node->clone_of
613 || node->decl != node->clone_of->decl))
614 continue;
616 /* Don't profile functions produced for builtin stuff. */
617 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
618 continue;
620 cgraph_set_const_flag (node, false, false);
621 cgraph_set_pure_flag (node, false, false);
624 /* Update call statements and rebuild the cgraph. */
625 FOR_EACH_DEFINED_FUNCTION (node)
627 basic_block bb;
629 if (!gimple_has_body_p (node->decl)
630 || !(!node->clone_of
631 || node->decl != node->clone_of->decl))
632 continue;
634 /* Don't profile functions produced for builtin stuff. */
635 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
636 continue;
638 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
640 FOR_EACH_BB_FN (bb, cfun)
642 gimple_stmt_iterator gsi;
643 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
645 gimple stmt = gsi_stmt (gsi);
646 if (is_gimple_call (stmt))
647 update_stmt (stmt);
651 /* re-merge split blocks. */
652 cleanup_tree_cfg ();
653 update_ssa (TODO_update_ssa);
655 rebuild_cgraph_edges ();
657 pop_cfun ();
660 handle_missing_profiles ();
662 del_node_map ();
663 return 0;
666 /* When profile instrumentation, use or test coverage shall be performed. */
668 static bool
669 gate_tree_profile_ipa (void)
671 return (!in_lto_p
672 && (flag_branch_probabilities || flag_test_coverage
673 || profile_arc_flag));
676 namespace {
678 const pass_data pass_data_ipa_tree_profile =
680 SIMPLE_IPA_PASS, /* type */
681 "profile", /* name */
682 OPTGROUP_NONE, /* optinfo_flags */
683 true, /* has_gate */
684 true, /* has_execute */
685 TV_IPA_PROFILE, /* tv_id */
686 0, /* properties_required */
687 0, /* properties_provided */
688 0, /* properties_destroyed */
689 0, /* todo_flags_start */
690 0, /* todo_flags_finish */
693 class pass_ipa_tree_profile : public simple_ipa_opt_pass
695 public:
696 pass_ipa_tree_profile (gcc::context *ctxt)
697 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
700 /* opt_pass methods: */
701 bool gate () { return gate_tree_profile_ipa (); }
702 unsigned int execute () { return tree_profiling (); }
704 }; // class pass_ipa_tree_profile
706 } // anon namespace
708 simple_ipa_opt_pass *
709 make_pass_ipa_tree_profile (gcc::context *ctxt)
711 return new pass_ipa_tree_profile (ctxt);
714 #include "gt-tree-profile.h"