2014-10-27 Andrew MacLeod <amacleod@redhat.com>
[official-gcc.git] / gcc / tree-profile.c
blob70a51f6cd90bb5acdc49af955ce814d7461ec4de
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 "hashtab.h"
33 #include "hash-set.h"
34 #include "vec.h"
35 #include "machmode.h"
36 #include "hard-reg-set.h"
37 #include "input.h"
38 #include "function.h"
39 #include "predict.h"
40 #include "dominance.h"
41 #include "cfg.h"
42 #include "basic-block.h"
43 #include "diagnostic-core.h"
44 #include "coverage.h"
45 #include "tree.h"
46 #include "tree-ssa-alias.h"
47 #include "internal-fn.h"
48 #include "gimple-expr.h"
49 #include "is-a.h"
50 #include "gimple.h"
51 #include "varasm.h"
52 #include "tree-nested.h"
53 #include "gimplify.h"
54 #include "gimple-iterator.h"
55 #include "gimplify-me.h"
56 #include "gimple-ssa.h"
57 #include "cgraph.h"
58 #include "tree-cfg.h"
59 #include "stringpool.h"
60 #include "tree-ssanames.h"
61 #include "tree-into-ssa.h"
62 #include "tree-pass.h"
63 #include "value-prof.h"
64 #include "profile.h"
65 #include "target.h"
66 #include "tree-cfgcleanup.h"
67 #include "tree-nested.h"
68 #include "params.h"
70 static GTY(()) tree gcov_type_node;
71 static GTY(()) tree tree_interval_profiler_fn;
72 static GTY(()) tree tree_pow2_profiler_fn;
73 static GTY(()) tree tree_one_value_profiler_fn;
74 static GTY(()) tree tree_indirect_call_profiler_fn;
75 static GTY(()) tree tree_time_profiler_fn;
76 static GTY(()) tree tree_average_profiler_fn;
77 static GTY(()) tree tree_ior_profiler_fn;
80 static GTY(()) tree ic_void_ptr_var;
81 static GTY(()) tree ic_gcov_type_ptr_var;
82 static GTY(()) tree ptr_void;
84 /* Do initialization work for the edge profiler. */
86 /* Add code:
87 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
88 __thread void* __gcov_indirect_call_callee; // actual callee address
89 __thread int __gcov_function_counter; // time profiler function counter
91 static void
92 init_ic_make_global_vars (void)
94 tree gcov_type_ptr;
96 ptr_void = build_pointer_type (void_type_node);
98 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
99 if (flag_lto)
101 ic_void_ptr_var
102 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
103 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
104 ptr_void);
105 TREE_PUBLIC (ic_void_ptr_var) = 1;
106 DECL_COMMON (ic_void_ptr_var) = 1;
107 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
108 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
110 else
112 ic_void_ptr_var
113 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
114 get_identifier (
115 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
116 "__gcov_indirect_call_topn_callee" :
117 "__gcov_indirect_call_callee")),
118 ptr_void);
119 TREE_PUBLIC (ic_void_ptr_var) = 1;
120 DECL_EXTERNAL (ic_void_ptr_var) = 1;
122 TREE_STATIC (ic_void_ptr_var) = 1;
123 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
124 DECL_INITIAL (ic_void_ptr_var) = NULL;
125 if (targetm.have_tls)
126 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
128 varpool_node::finalize_decl (ic_void_ptr_var);
130 gcov_type_ptr = build_pointer_type (get_gcov_type ());
131 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
132 if (flag_lto)
134 ic_gcov_type_ptr_var
135 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
136 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
137 gcov_type_ptr);
138 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
139 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
140 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
141 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
143 else
145 ic_gcov_type_ptr_var
146 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
147 get_identifier (
148 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
149 "__gcov_indirect_call_topn_counters" :
150 "__gcov_indirect_call_counters")),
151 gcov_type_ptr);
152 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
153 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
155 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
156 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
157 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
158 if (targetm.have_tls)
159 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
161 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
164 /* Create the type and function decls for the interface with gcov. */
166 void
167 gimple_init_edge_profiler (void)
169 tree interval_profiler_fn_type;
170 tree pow2_profiler_fn_type;
171 tree one_value_profiler_fn_type;
172 tree gcov_type_ptr;
173 tree ic_profiler_fn_type;
174 tree average_profiler_fn_type;
175 tree time_profiler_fn_type;
177 if (!gcov_type_node)
179 gcov_type_node = get_gcov_type ();
180 gcov_type_ptr = build_pointer_type (gcov_type_node);
182 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
183 interval_profiler_fn_type
184 = build_function_type_list (void_type_node,
185 gcov_type_ptr, gcov_type_node,
186 integer_type_node,
187 unsigned_type_node, NULL_TREE);
188 tree_interval_profiler_fn
189 = build_fn_decl ("__gcov_interval_profiler",
190 interval_profiler_fn_type);
191 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
192 DECL_ATTRIBUTES (tree_interval_profiler_fn)
193 = tree_cons (get_identifier ("leaf"), NULL,
194 DECL_ATTRIBUTES (tree_interval_profiler_fn));
196 /* void (*) (gcov_type *, gcov_type) */
197 pow2_profiler_fn_type
198 = build_function_type_list (void_type_node,
199 gcov_type_ptr, gcov_type_node,
200 NULL_TREE);
201 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
202 pow2_profiler_fn_type);
203 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
204 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
205 = tree_cons (get_identifier ("leaf"), NULL,
206 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
208 /* void (*) (gcov_type *, gcov_type) */
209 one_value_profiler_fn_type
210 = build_function_type_list (void_type_node,
211 gcov_type_ptr, gcov_type_node,
212 NULL_TREE);
213 tree_one_value_profiler_fn
214 = build_fn_decl ("__gcov_one_value_profiler",
215 one_value_profiler_fn_type);
216 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
217 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
218 = tree_cons (get_identifier ("leaf"), NULL,
219 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
221 init_ic_make_global_vars ();
223 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
224 if (flag_lto)
226 /* void (*) (gcov_type, void *) */
227 ic_profiler_fn_type
228 = build_function_type_list (void_type_node,
229 gcov_type_ptr, gcov_type_node,
230 ptr_void, ptr_void,
231 NULL_TREE);
232 tree_indirect_call_profiler_fn
233 = build_fn_decl ("__gcov_indirect_call_profiler",
234 ic_profiler_fn_type);
236 else
238 /* void (*) (gcov_type, void *) */
239 ic_profiler_fn_type
240 = build_function_type_list (void_type_node,
241 gcov_type_node,
242 ptr_void,
243 NULL_TREE);
244 tree_indirect_call_profiler_fn
245 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
246 "__gcov_indirect_call_topn_profiler":
247 "__gcov_indirect_call_profiler_v2"),
248 ic_profiler_fn_type);
250 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
251 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
252 = tree_cons (get_identifier ("leaf"), NULL,
253 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
255 /* void (*) (gcov_type *, gcov_type, void *) */
256 time_profiler_fn_type
257 = build_function_type_list (void_type_node,
258 gcov_type_ptr, NULL_TREE);
259 tree_time_profiler_fn
260 = build_fn_decl ("__gcov_time_profiler",
261 time_profiler_fn_type);
262 TREE_NOTHROW (tree_time_profiler_fn) = 1;
263 DECL_ATTRIBUTES (tree_time_profiler_fn)
264 = tree_cons (get_identifier ("leaf"), NULL,
265 DECL_ATTRIBUTES (tree_time_profiler_fn));
267 /* void (*) (gcov_type *, gcov_type) */
268 average_profiler_fn_type
269 = build_function_type_list (void_type_node,
270 gcov_type_ptr, gcov_type_node, NULL_TREE);
271 tree_average_profiler_fn
272 = build_fn_decl ("__gcov_average_profiler",
273 average_profiler_fn_type);
274 TREE_NOTHROW (tree_average_profiler_fn) = 1;
275 DECL_ATTRIBUTES (tree_average_profiler_fn)
276 = tree_cons (get_identifier ("leaf"), NULL,
277 DECL_ATTRIBUTES (tree_average_profiler_fn));
278 tree_ior_profiler_fn
279 = build_fn_decl ("__gcov_ior_profiler",
280 average_profiler_fn_type);
281 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
282 DECL_ATTRIBUTES (tree_ior_profiler_fn)
283 = tree_cons (get_identifier ("leaf"), NULL,
284 DECL_ATTRIBUTES (tree_ior_profiler_fn));
286 /* LTO streamer needs assembler names. Because we create these decls
287 late, we need to initialize them by hand. */
288 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
289 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
290 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
291 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
292 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
293 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
294 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
298 /* Output instructions as GIMPLE trees to increment the edge
299 execution count, and insert them on E. We rely on
300 gsi_insert_on_edge to preserve the order. */
302 void
303 gimple_gen_edge_profiler (int edgeno, edge e)
305 tree ref, one, gcov_type_tmp_var;
306 gimple stmt1, stmt2, stmt3;
308 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
309 one = build_int_cst (gcov_type_node, 1);
310 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
311 NULL, "PROF_edge_counter");
312 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
313 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
314 NULL, "PROF_edge_counter");
315 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
316 gimple_assign_lhs (stmt1), one);
317 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
318 gsi_insert_on_edge (e, stmt1);
319 gsi_insert_on_edge (e, stmt2);
320 gsi_insert_on_edge (e, stmt3);
323 /* Emits code to get VALUE to instrument at GSI, and returns the
324 variable containing the value. */
326 static tree
327 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
329 tree val = value->hvalue.value;
330 if (POINTER_TYPE_P (TREE_TYPE (val)))
331 val = fold_convert (build_nonstandard_integer_type
332 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
333 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
334 true, NULL_TREE, true, GSI_SAME_STMT);
337 /* Output instructions as GIMPLE trees to increment the interval histogram
338 counter. VALUE is the expression whose value is profiled. TAG is the
339 tag of the section for counters, BASE is offset of the counter position. */
341 void
342 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
344 gimple stmt = value->hvalue.stmt;
345 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
346 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
347 gimple call;
348 tree val;
349 tree start = build_int_cst_type (integer_type_node,
350 value->hdata.intvl.int_start);
351 tree steps = build_int_cst_type (unsigned_type_node,
352 value->hdata.intvl.steps);
354 ref_ptr = force_gimple_operand_gsi (&gsi,
355 build_addr (ref, current_function_decl),
356 true, NULL_TREE, true, GSI_SAME_STMT);
357 val = prepare_instrumented_value (&gsi, value);
358 call = gimple_build_call (tree_interval_profiler_fn, 4,
359 ref_ptr, val, start, steps);
360 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
363 /* Output instructions as GIMPLE trees to increment the power of two histogram
364 counter. VALUE is the expression whose value is profiled. TAG is the tag
365 of the section for counters, BASE is offset of the counter position. */
367 void
368 gimple_gen_pow2_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_pow2_profiler_fn, 2, ref_ptr, val);
380 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
383 /* Output instructions as GIMPLE trees for code to find the most common value.
384 VALUE is the expression whose value is profiled. TAG is the tag of the
385 section for counters, BASE is offset of the counter position. */
387 void
388 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
390 gimple stmt = value->hvalue.stmt;
391 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
392 tree ref_ptr = tree_coverage_counter_addr (tag, base);
393 gimple call;
394 tree val;
396 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
397 true, NULL_TREE, true, GSI_SAME_STMT);
398 val = prepare_instrumented_value (&gsi, value);
399 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
400 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
404 /* Output instructions as GIMPLE trees for code to find the most
405 common called function in indirect call.
406 VALUE is the call expression whose indirect callee is profiled.
407 TAG is the tag of the section for counters, BASE is offset of the
408 counter position. */
410 void
411 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
413 tree tmp1;
414 gimple stmt1, stmt2, stmt3;
415 gimple stmt = value->hvalue.stmt;
416 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
417 tree ref_ptr = tree_coverage_counter_addr (tag, base);
419 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
420 tag == GCOV_COUNTER_V_INDIR) ||
421 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
422 tag == GCOV_COUNTER_ICALL_TOPNV))
423 return;
425 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
426 true, NULL_TREE, true, GSI_SAME_STMT);
428 /* Insert code:
430 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
431 stmt2: tmp1 = (void *) (indirect call argument value)
432 stmt3: __gcov_indirect_call_callee = tmp1;
435 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
436 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
437 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
438 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
440 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
441 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
442 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
446 /* Output instructions as GIMPLE trees for code to find the most
447 common called function in indirect call. Insert instructions at the
448 beginning of every possible called function.
451 void
452 gimple_gen_ic_func_profiler (void)
454 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
455 gimple_stmt_iterator gsi;
456 gimple stmt1, stmt2;
457 tree tree_uid, cur_func, void0;
459 if (c_node->only_called_directly_p ())
460 return;
462 gimple_init_edge_profiler ();
464 /* Insert code:
466 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
467 &current_function_decl)
469 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
471 cur_func = force_gimple_operand_gsi (&gsi,
472 build_addr (current_function_decl,
473 current_function_decl),
474 true, NULL_TREE,
475 true, GSI_SAME_STMT);
476 tree_uid = build_int_cst
477 (gcov_type_node, cgraph_node::get (current_function_decl)->profile_id);
478 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
479 if (flag_lto)
481 tree counter_ptr, ptr_var;
482 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
483 true, NULL_TREE, true,
484 GSI_SAME_STMT);
485 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
486 true, NULL_TREE, true,
487 GSI_SAME_STMT);
489 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
490 counter_ptr, tree_uid, cur_func, ptr_var);
492 else
494 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
495 tree_uid, cur_func);
497 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
499 /* Set __gcov_indirect_call_callee to 0,
500 so that calls from other modules won't get misattributed
501 to the last caller of the current callee. */
502 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
503 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
504 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
507 /* Output instructions as GIMPLE tree at the beginning for each function.
508 TAG is the tag of the section for counters, BASE is offset of the
509 counter position and GSI is the iterator we place the counter. */
511 void
512 gimple_gen_time_profiler (unsigned tag, unsigned base,
513 gimple_stmt_iterator &gsi)
515 tree ref_ptr = tree_coverage_counter_addr (tag, base);
516 gimple call;
518 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
519 true, NULL_TREE, true, GSI_SAME_STMT);
520 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
521 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
524 /* Output instructions as GIMPLE trees for code to find the most common value
525 of a difference between two evaluations of an expression.
526 VALUE is the expression whose value is profiled. TAG is the tag of the
527 section for counters, BASE is offset of the counter position. */
529 void
530 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
531 unsigned tag ATTRIBUTE_UNUSED,
532 unsigned base ATTRIBUTE_UNUSED)
534 /* FIXME implement this. */
535 #ifdef ENABLE_CHECKING
536 internal_error ("unimplemented functionality");
537 #endif
538 gcc_unreachable ();
541 /* Output instructions as GIMPLE trees to increment the average 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_average_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,
556 true, GSI_SAME_STMT);
557 val = prepare_instrumented_value (&gsi, value);
558 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
559 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
562 /* Output instructions as GIMPLE trees to increment the ior histogram
563 counter. VALUE is the expression whose value is profiled. TAG is the
564 tag of the section for counters, BASE is offset of the counter position. */
566 void
567 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
569 gimple stmt = value->hvalue.stmt;
570 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
571 tree ref_ptr = tree_coverage_counter_addr (tag, base);
572 gimple call;
573 tree val;
575 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
576 true, NULL_TREE, true, GSI_SAME_STMT);
577 val = prepare_instrumented_value (&gsi, value);
578 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
579 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
582 /* Profile all functions in the callgraph. */
584 static unsigned int
585 tree_profiling (void)
587 struct cgraph_node *node;
589 /* This is a small-ipa pass that gets called only once, from
590 cgraphunit.c:ipa_passes(). */
591 gcc_assert (symtab->state == IPA_SSA);
593 init_node_map (true);
595 FOR_EACH_DEFINED_FUNCTION (node)
597 if (!gimple_has_body_p (node->decl))
598 continue;
600 /* Don't profile functions produced for builtin stuff. */
601 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
602 continue;
604 /* Do not instrument extern inline functions when testing coverage.
605 While this is not perfectly consistent (early inlined extern inlines
606 will get acocunted), testsuite expects that. */
607 if (DECL_EXTERNAL (node->decl)
608 && flag_test_coverage)
609 continue;
611 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
613 /* Local pure-const may imply need to fixup the cfg. */
614 if (execute_fixup_cfg () & TODO_cleanup_cfg)
615 cleanup_tree_cfg ();
617 branch_prob ();
619 if (! flag_branch_probabilities
620 && flag_profile_values)
621 gimple_gen_ic_func_profiler ();
623 if (flag_branch_probabilities
624 && flag_profile_values
625 && flag_value_profile_transformations)
626 gimple_value_profile_transformations ();
628 /* The above could hose dominator info. Currently there is
629 none coming in, this is a safety valve. It should be
630 easy to adjust it, if and when there is some. */
631 free_dominance_info (CDI_DOMINATORS);
632 free_dominance_info (CDI_POST_DOMINATORS);
633 pop_cfun ();
636 /* Drop pure/const flags from instrumented functions. */
637 FOR_EACH_DEFINED_FUNCTION (node)
639 if (!gimple_has_body_p (node->decl)
640 || !(!node->clone_of
641 || node->decl != node->clone_of->decl))
642 continue;
644 /* Don't profile functions produced for builtin stuff. */
645 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
646 continue;
648 node->set_const_flag (false, false);
649 node->set_pure_flag (false, false);
652 /* Update call statements and rebuild the cgraph. */
653 FOR_EACH_DEFINED_FUNCTION (node)
655 basic_block bb;
657 if (!gimple_has_body_p (node->decl)
658 || !(!node->clone_of
659 || node->decl != node->clone_of->decl))
660 continue;
662 /* Don't profile functions produced for builtin stuff. */
663 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
664 continue;
666 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
668 FOR_EACH_BB_FN (bb, cfun)
670 gimple_stmt_iterator gsi;
671 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
673 gimple stmt = gsi_stmt (gsi);
674 if (is_gimple_call (stmt))
675 update_stmt (stmt);
679 /* re-merge split blocks. */
680 cleanup_tree_cfg ();
681 update_ssa (TODO_update_ssa);
683 cgraph_edge::rebuild_edges ();
685 pop_cfun ();
688 handle_missing_profiles ();
690 del_node_map ();
691 return 0;
694 namespace {
696 const pass_data pass_data_ipa_tree_profile =
698 SIMPLE_IPA_PASS, /* type */
699 "profile", /* name */
700 OPTGROUP_NONE, /* optinfo_flags */
701 TV_IPA_PROFILE, /* tv_id */
702 0, /* properties_required */
703 0, /* properties_provided */
704 0, /* properties_destroyed */
705 0, /* todo_flags_start */
706 0, /* todo_flags_finish */
709 class pass_ipa_tree_profile : public simple_ipa_opt_pass
711 public:
712 pass_ipa_tree_profile (gcc::context *ctxt)
713 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
716 /* opt_pass methods: */
717 virtual bool gate (function *);
718 virtual unsigned int execute (function *) { return tree_profiling (); }
720 }; // class pass_ipa_tree_profile
722 bool
723 pass_ipa_tree_profile::gate (function *)
725 /* When profile instrumentation, use or test coverage shall be performed.
726 But for AutoFDO, this there is no instrumentation, thus this pass is
727 diabled. */
728 return (!in_lto_p && !flag_auto_profile
729 && (flag_branch_probabilities || flag_test_coverage
730 || profile_arc_flag));
733 } // anon namespace
735 simple_ipa_opt_pass *
736 make_pass_ipa_tree_profile (gcc::context *ctxt)
738 return new pass_ipa_tree_profile (ctxt);
741 #include "gt-tree-profile.h"