* pt.c (lookup_template_class_1): Splice out abi_tag attribute if
[official-gcc.git] / gcc / tree-profile.c
blobba90196c7ce08a2e11593253bb906ac46604e5c2
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2014 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 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
115 varpool_node::finalize_decl (ic_void_ptr_var);
117 gcov_type_ptr = build_pointer_type (get_gcov_type ());
118 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
119 if (flag_lto)
121 ic_gcov_type_ptr_var
122 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
123 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
124 gcov_type_ptr);
125 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
126 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
127 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
128 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
130 else
132 ic_gcov_type_ptr_var
133 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
134 get_identifier ("__gcov_indirect_call_counters"),
135 gcov_type_ptr);
136 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
137 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
139 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
140 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
141 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
142 if (targetm.have_tls)
143 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
145 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
148 /* Create the type and function decls for the interface with gcov. */
150 void
151 gimple_init_edge_profiler (void)
153 tree interval_profiler_fn_type;
154 tree pow2_profiler_fn_type;
155 tree one_value_profiler_fn_type;
156 tree gcov_type_ptr;
157 tree ic_profiler_fn_type;
158 tree average_profiler_fn_type;
159 tree time_profiler_fn_type;
161 if (!gcov_type_node)
163 gcov_type_node = get_gcov_type ();
164 gcov_type_ptr = build_pointer_type (gcov_type_node);
166 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
167 interval_profiler_fn_type
168 = build_function_type_list (void_type_node,
169 gcov_type_ptr, gcov_type_node,
170 integer_type_node,
171 unsigned_type_node, NULL_TREE);
172 tree_interval_profiler_fn
173 = build_fn_decl ("__gcov_interval_profiler",
174 interval_profiler_fn_type);
175 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
176 DECL_ATTRIBUTES (tree_interval_profiler_fn)
177 = tree_cons (get_identifier ("leaf"), NULL,
178 DECL_ATTRIBUTES (tree_interval_profiler_fn));
180 /* void (*) (gcov_type *, gcov_type) */
181 pow2_profiler_fn_type
182 = build_function_type_list (void_type_node,
183 gcov_type_ptr, gcov_type_node,
184 NULL_TREE);
185 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
186 pow2_profiler_fn_type);
187 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
188 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
189 = tree_cons (get_identifier ("leaf"), NULL,
190 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
192 /* void (*) (gcov_type *, gcov_type) */
193 one_value_profiler_fn_type
194 = build_function_type_list (void_type_node,
195 gcov_type_ptr, gcov_type_node,
196 NULL_TREE);
197 tree_one_value_profiler_fn
198 = build_fn_decl ("__gcov_one_value_profiler",
199 one_value_profiler_fn_type);
200 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
201 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
202 = tree_cons (get_identifier ("leaf"), NULL,
203 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
205 init_ic_make_global_vars ();
207 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
208 if (flag_lto)
210 /* void (*) (gcov_type, void *) */
211 ic_profiler_fn_type
212 = build_function_type_list (void_type_node,
213 gcov_type_ptr, gcov_type_node,
214 ptr_void, ptr_void,
215 NULL_TREE);
216 tree_indirect_call_profiler_fn
217 = build_fn_decl ("__gcov_indirect_call_profiler",
218 ic_profiler_fn_type);
220 else
222 /* void (*) (gcov_type, void *) */
223 ic_profiler_fn_type
224 = build_function_type_list (void_type_node,
225 gcov_type_node,
226 ptr_void,
227 NULL_TREE);
228 tree_indirect_call_profiler_fn
229 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
230 ic_profiler_fn_type);
232 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
233 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
234 = tree_cons (get_identifier ("leaf"), NULL,
235 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
237 /* void (*) (gcov_type *, gcov_type, void *) */
238 time_profiler_fn_type
239 = build_function_type_list (void_type_node,
240 gcov_type_ptr, NULL_TREE);
241 tree_time_profiler_fn
242 = build_fn_decl ("__gcov_time_profiler",
243 time_profiler_fn_type);
244 TREE_NOTHROW (tree_time_profiler_fn) = 1;
245 DECL_ATTRIBUTES (tree_time_profiler_fn)
246 = tree_cons (get_identifier ("leaf"), NULL,
247 DECL_ATTRIBUTES (tree_time_profiler_fn));
249 /* void (*) (gcov_type *, gcov_type) */
250 average_profiler_fn_type
251 = build_function_type_list (void_type_node,
252 gcov_type_ptr, gcov_type_node, NULL_TREE);
253 tree_average_profiler_fn
254 = build_fn_decl ("__gcov_average_profiler",
255 average_profiler_fn_type);
256 TREE_NOTHROW (tree_average_profiler_fn) = 1;
257 DECL_ATTRIBUTES (tree_average_profiler_fn)
258 = tree_cons (get_identifier ("leaf"), NULL,
259 DECL_ATTRIBUTES (tree_average_profiler_fn));
260 tree_ior_profiler_fn
261 = build_fn_decl ("__gcov_ior_profiler",
262 average_profiler_fn_type);
263 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
264 DECL_ATTRIBUTES (tree_ior_profiler_fn)
265 = tree_cons (get_identifier ("leaf"), NULL,
266 DECL_ATTRIBUTES (tree_ior_profiler_fn));
268 /* LTO streamer needs assembler names. Because we create these decls
269 late, we need to initialize them by hand. */
270 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
271 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
272 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
273 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
274 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
275 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
276 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
280 /* Output instructions as GIMPLE trees to increment the edge
281 execution count, and insert them on E. We rely on
282 gsi_insert_on_edge to preserve the order. */
284 void
285 gimple_gen_edge_profiler (int edgeno, edge e)
287 tree ref, one, gcov_type_tmp_var;
288 gimple stmt1, stmt2, stmt3;
290 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
291 one = build_int_cst (gcov_type_node, 1);
292 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
293 NULL, "PROF_edge_counter");
294 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
295 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
296 NULL, "PROF_edge_counter");
297 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
298 gimple_assign_lhs (stmt1), one);
299 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
300 gsi_insert_on_edge (e, stmt1);
301 gsi_insert_on_edge (e, stmt2);
302 gsi_insert_on_edge (e, stmt3);
305 /* Emits code to get VALUE to instrument at GSI, and returns the
306 variable containing the value. */
308 static tree
309 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
311 tree val = value->hvalue.value;
312 if (POINTER_TYPE_P (TREE_TYPE (val)))
313 val = fold_convert (build_nonstandard_integer_type
314 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
315 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
316 true, NULL_TREE, true, GSI_SAME_STMT);
319 /* Output instructions as GIMPLE trees to increment the interval histogram
320 counter. VALUE is the expression whose value is profiled. TAG is the
321 tag of the section for counters, BASE is offset of the counter position. */
323 void
324 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
326 gimple stmt = value->hvalue.stmt;
327 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
328 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
329 gimple call;
330 tree val;
331 tree start = build_int_cst_type (integer_type_node,
332 value->hdata.intvl.int_start);
333 tree steps = build_int_cst_type (unsigned_type_node,
334 value->hdata.intvl.steps);
336 ref_ptr = force_gimple_operand_gsi (&gsi,
337 build_addr (ref, current_function_decl),
338 true, NULL_TREE, true, GSI_SAME_STMT);
339 val = prepare_instrumented_value (&gsi, value);
340 call = gimple_build_call (tree_interval_profiler_fn, 4,
341 ref_ptr, val, start, steps);
342 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
345 /* Output instructions as GIMPLE trees to increment the power of two histogram
346 counter. VALUE is the expression whose value is profiled. TAG is the tag
347 of the section for counters, BASE is offset of the counter position. */
349 void
350 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
352 gimple stmt = value->hvalue.stmt;
353 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
354 tree ref_ptr = tree_coverage_counter_addr (tag, base);
355 gimple call;
356 tree val;
358 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
359 true, NULL_TREE, true, GSI_SAME_STMT);
360 val = prepare_instrumented_value (&gsi, value);
361 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
362 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
365 /* Output instructions as GIMPLE trees for code to find the most common value.
366 VALUE is the expression whose value is profiled. TAG is the tag of the
367 section for counters, BASE is offset of the counter position. */
369 void
370 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
372 gimple stmt = value->hvalue.stmt;
373 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
374 tree ref_ptr = tree_coverage_counter_addr (tag, base);
375 gimple call;
376 tree val;
378 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
379 true, NULL_TREE, true, GSI_SAME_STMT);
380 val = prepare_instrumented_value (&gsi, value);
381 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
382 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
386 /* Output instructions as GIMPLE trees for code to find the most
387 common called function in indirect call.
388 VALUE is the call expression whose indirect callee is profiled.
389 TAG is the tag of the section for counters, BASE is offset of the
390 counter position. */
392 void
393 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
395 tree tmp1;
396 gimple stmt1, stmt2, stmt3;
397 gimple stmt = value->hvalue.stmt;
398 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
399 tree ref_ptr = tree_coverage_counter_addr (tag, base);
401 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
402 true, NULL_TREE, true, GSI_SAME_STMT);
404 /* Insert code:
406 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
407 stmt2: tmp1 = (void *) (indirect call argument value)
408 stmt3: __gcov_indirect_call_callee = tmp1;
411 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
412 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
413 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
414 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
416 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
417 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
418 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
422 /* Output instructions as GIMPLE trees for code to find the most
423 common called function in indirect call. Insert instructions at the
424 beginning of every possible called function.
427 void
428 gimple_gen_ic_func_profiler (void)
430 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
431 gimple_stmt_iterator gsi;
432 gimple stmt1, stmt2;
433 tree tree_uid, cur_func, void0;
435 if (c_node->only_called_directly_p ())
436 return;
438 gimple_init_edge_profiler ();
440 /* Insert code:
442 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
443 &current_function_decl)
445 gsi =
446 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
448 cur_func = force_gimple_operand_gsi (&gsi,
449 build_addr (current_function_decl,
450 current_function_decl),
451 true, NULL_TREE,
452 true, GSI_SAME_STMT);
453 tree_uid = build_int_cst
454 (gcov_type_node, cgraph_node::get (current_function_decl)->profile_id);
455 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
456 if (flag_lto)
458 tree counter_ptr, ptr_var;
459 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
460 true, NULL_TREE, true,
461 GSI_SAME_STMT);
462 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
463 true, NULL_TREE, true,
464 GSI_SAME_STMT);
466 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
467 counter_ptr, tree_uid, cur_func, ptr_var);
469 else
471 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
472 tree_uid, cur_func);
474 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
476 /* Set __gcov_indirect_call_callee to 0,
477 so that calls from other modules won't get misattributed
478 to the last caller of the current callee. */
479 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
480 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
481 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
484 /* Output instructions as GIMPLE tree at the beginning for each function.
485 TAG is the tag of the section for counters, BASE is offset of the
486 counter position and GSI is the iterator we place the counter. */
488 void
489 gimple_gen_time_profiler (unsigned tag, unsigned base,
490 gimple_stmt_iterator &gsi)
492 tree ref_ptr = tree_coverage_counter_addr (tag, base);
493 gimple call;
495 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
496 true, NULL_TREE, true, GSI_SAME_STMT);
497 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
498 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
501 /* Output instructions as GIMPLE trees for code to find the most common value
502 of a difference between two evaluations of an expression.
503 VALUE is the expression whose value is profiled. TAG is the tag of the
504 section for counters, BASE is offset of the counter position. */
506 void
507 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
508 unsigned tag ATTRIBUTE_UNUSED,
509 unsigned base ATTRIBUTE_UNUSED)
511 /* FIXME implement this. */
512 #ifdef ENABLE_CHECKING
513 internal_error ("unimplemented functionality");
514 #endif
515 gcc_unreachable ();
518 /* Output instructions as GIMPLE trees to increment the average histogram
519 counter. VALUE is the expression whose value is profiled. TAG is the
520 tag of the section for counters, BASE is offset of the counter position. */
522 void
523 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
525 gimple stmt = value->hvalue.stmt;
526 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
527 tree ref_ptr = tree_coverage_counter_addr (tag, base);
528 gimple call;
529 tree val;
531 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
532 true, NULL_TREE,
533 true, GSI_SAME_STMT);
534 val = prepare_instrumented_value (&gsi, value);
535 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
536 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
539 /* Output instructions as GIMPLE trees to increment the ior histogram
540 counter. VALUE is the expression whose value is profiled. TAG is the
541 tag of the section for counters, BASE is offset of the counter position. */
543 void
544 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
546 gimple stmt = value->hvalue.stmt;
547 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
548 tree ref_ptr = tree_coverage_counter_addr (tag, base);
549 gimple call;
550 tree val;
552 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
553 true, NULL_TREE, true, GSI_SAME_STMT);
554 val = prepare_instrumented_value (&gsi, value);
555 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
556 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
559 /* Profile all functions in the callgraph. */
561 static unsigned int
562 tree_profiling (void)
564 struct cgraph_node *node;
566 /* This is a small-ipa pass that gets called only once, from
567 cgraphunit.c:ipa_passes(). */
568 gcc_assert (symtab->state == IPA_SSA);
570 init_node_map (true);
572 FOR_EACH_DEFINED_FUNCTION (node)
574 if (!gimple_has_body_p (node->decl))
575 continue;
577 /* Don't profile functions produced for builtin stuff. */
578 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
579 continue;
581 /* Do not instrument extern inline functions when testing coverage.
582 While this is not perfectly consistent (early inlined extern inlines
583 will get acocunted), testsuite expects that. */
584 if (DECL_EXTERNAL (node->decl)
585 && flag_test_coverage)
586 continue;
588 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
590 /* Local pure-const may imply need to fixup the cfg. */
591 if (execute_fixup_cfg () & TODO_cleanup_cfg)
592 cleanup_tree_cfg ();
594 branch_prob ();
596 if (! flag_branch_probabilities
597 && flag_profile_values)
598 gimple_gen_ic_func_profiler ();
600 if (flag_branch_probabilities
601 && flag_profile_values
602 && flag_value_profile_transformations)
603 gimple_value_profile_transformations ();
605 /* The above could hose dominator info. Currently there is
606 none coming in, this is a safety valve. It should be
607 easy to adjust it, if and when there is some. */
608 free_dominance_info (CDI_DOMINATORS);
609 free_dominance_info (CDI_POST_DOMINATORS);
610 pop_cfun ();
613 /* Drop pure/const flags from instrumented functions. */
614 FOR_EACH_DEFINED_FUNCTION (node)
616 if (!gimple_has_body_p (node->decl)
617 || !(!node->clone_of
618 || node->decl != node->clone_of->decl))
619 continue;
621 /* Don't profile functions produced for builtin stuff. */
622 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
623 continue;
625 node->set_const_flag (false, false);
626 node->set_pure_flag (false, false);
629 /* Update call statements and rebuild the cgraph. */
630 FOR_EACH_DEFINED_FUNCTION (node)
632 basic_block bb;
634 if (!gimple_has_body_p (node->decl)
635 || !(!node->clone_of
636 || node->decl != node->clone_of->decl))
637 continue;
639 /* Don't profile functions produced for builtin stuff. */
640 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
641 continue;
643 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
645 FOR_EACH_BB_FN (bb, cfun)
647 gimple_stmt_iterator gsi;
648 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
650 gimple stmt = gsi_stmt (gsi);
651 if (is_gimple_call (stmt))
652 update_stmt (stmt);
656 /* re-merge split blocks. */
657 cleanup_tree_cfg ();
658 update_ssa (TODO_update_ssa);
660 cgraph_edge::rebuild_edges ();
662 pop_cfun ();
665 handle_missing_profiles ();
667 del_node_map ();
668 return 0;
671 namespace {
673 const pass_data pass_data_ipa_tree_profile =
675 SIMPLE_IPA_PASS, /* type */
676 "profile", /* name */
677 OPTGROUP_NONE, /* optinfo_flags */
678 TV_IPA_PROFILE, /* tv_id */
679 0, /* properties_required */
680 0, /* properties_provided */
681 0, /* properties_destroyed */
682 0, /* todo_flags_start */
683 0, /* todo_flags_finish */
686 class pass_ipa_tree_profile : public simple_ipa_opt_pass
688 public:
689 pass_ipa_tree_profile (gcc::context *ctxt)
690 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
693 /* opt_pass methods: */
694 virtual bool gate (function *);
695 virtual unsigned int execute (function *) { return tree_profiling (); }
697 }; // class pass_ipa_tree_profile
699 bool
700 pass_ipa_tree_profile::gate (function *)
702 /* When profile instrumentation, use or test coverage shall be performed. */
703 return (!in_lto_p
704 && (flag_branch_probabilities || flag_test_coverage
705 || profile_arc_flag));
708 } // anon namespace
710 simple_ipa_opt_pass *
711 make_pass_ipa_tree_profile (gcc::context *ctxt)
713 return new pass_ipa_tree_profile (ctxt);
716 #include "gt-tree-profile.h"