Concretize gimple_cond_set_{lhs|rhs}
[official-gcc.git] / gcc / tree-profile.c
blob558332201403acf2d64db73420f2333095e54afa
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"
59 #include "params.h"
61 static GTY(()) tree gcov_type_node;
62 static GTY(()) tree tree_interval_profiler_fn;
63 static GTY(()) tree tree_pow2_profiler_fn;
64 static GTY(()) tree tree_one_value_profiler_fn;
65 static GTY(()) tree tree_indirect_call_profiler_fn;
66 static GTY(()) tree tree_time_profiler_fn;
67 static GTY(()) tree tree_average_profiler_fn;
68 static GTY(()) tree tree_ior_profiler_fn;
71 static GTY(()) tree ic_void_ptr_var;
72 static GTY(()) tree ic_gcov_type_ptr_var;
73 static GTY(()) tree ptr_void;
75 /* Do initialization work for the edge profiler. */
77 /* Add code:
78 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
79 __thread void* __gcov_indirect_call_callee; // actual callee address
80 __thread int __gcov_function_counter; // time profiler function counter
82 static void
83 init_ic_make_global_vars (void)
85 tree gcov_type_ptr;
87 ptr_void = build_pointer_type (void_type_node);
89 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
90 if (flag_lto)
92 ic_void_ptr_var
93 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
94 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
95 ptr_void);
96 TREE_PUBLIC (ic_void_ptr_var) = 1;
97 DECL_COMMON (ic_void_ptr_var) = 1;
98 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
99 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
101 else
103 ic_void_ptr_var
104 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
105 get_identifier (
106 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
107 "__gcov_indirect_call_topn_callee" :
108 "__gcov_indirect_call_callee")),
109 ptr_void);
110 TREE_PUBLIC (ic_void_ptr_var) = 1;
111 DECL_EXTERNAL (ic_void_ptr_var) = 1;
113 TREE_STATIC (ic_void_ptr_var) = 1;
114 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
115 DECL_INITIAL (ic_void_ptr_var) = NULL;
116 if (targetm.have_tls)
117 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
119 varpool_node::finalize_decl (ic_void_ptr_var);
121 gcov_type_ptr = build_pointer_type (get_gcov_type ());
122 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
123 if (flag_lto)
125 ic_gcov_type_ptr_var
126 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
127 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
128 gcov_type_ptr);
129 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
130 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
131 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
132 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
134 else
136 ic_gcov_type_ptr_var
137 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
138 get_identifier (
139 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
140 "__gcov_indirect_call_topn_counters" :
141 "__gcov_indirect_call_counters")),
142 gcov_type_ptr);
143 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
144 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
146 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
147 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
148 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
149 if (targetm.have_tls)
150 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
152 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
155 /* Create the type and function decls for the interface with gcov. */
157 void
158 gimple_init_edge_profiler (void)
160 tree interval_profiler_fn_type;
161 tree pow2_profiler_fn_type;
162 tree one_value_profiler_fn_type;
163 tree gcov_type_ptr;
164 tree ic_profiler_fn_type;
165 tree average_profiler_fn_type;
166 tree time_profiler_fn_type;
168 if (!gcov_type_node)
170 gcov_type_node = get_gcov_type ();
171 gcov_type_ptr = build_pointer_type (gcov_type_node);
173 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
174 interval_profiler_fn_type
175 = build_function_type_list (void_type_node,
176 gcov_type_ptr, gcov_type_node,
177 integer_type_node,
178 unsigned_type_node, NULL_TREE);
179 tree_interval_profiler_fn
180 = build_fn_decl ("__gcov_interval_profiler",
181 interval_profiler_fn_type);
182 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
183 DECL_ATTRIBUTES (tree_interval_profiler_fn)
184 = tree_cons (get_identifier ("leaf"), NULL,
185 DECL_ATTRIBUTES (tree_interval_profiler_fn));
187 /* void (*) (gcov_type *, gcov_type) */
188 pow2_profiler_fn_type
189 = build_function_type_list (void_type_node,
190 gcov_type_ptr, gcov_type_node,
191 NULL_TREE);
192 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
193 pow2_profiler_fn_type);
194 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
195 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
196 = tree_cons (get_identifier ("leaf"), NULL,
197 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
199 /* void (*) (gcov_type *, gcov_type) */
200 one_value_profiler_fn_type
201 = build_function_type_list (void_type_node,
202 gcov_type_ptr, gcov_type_node,
203 NULL_TREE);
204 tree_one_value_profiler_fn
205 = build_fn_decl ("__gcov_one_value_profiler",
206 one_value_profiler_fn_type);
207 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
208 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
209 = tree_cons (get_identifier ("leaf"), NULL,
210 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
212 init_ic_make_global_vars ();
214 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
215 if (flag_lto)
217 /* void (*) (gcov_type, void *) */
218 ic_profiler_fn_type
219 = build_function_type_list (void_type_node,
220 gcov_type_ptr, gcov_type_node,
221 ptr_void, ptr_void,
222 NULL_TREE);
223 tree_indirect_call_profiler_fn
224 = build_fn_decl ("__gcov_indirect_call_profiler",
225 ic_profiler_fn_type);
227 else
229 /* void (*) (gcov_type, void *) */
230 ic_profiler_fn_type
231 = build_function_type_list (void_type_node,
232 gcov_type_node,
233 ptr_void,
234 NULL_TREE);
235 tree_indirect_call_profiler_fn
236 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
237 "__gcov_indirect_call_topn_profiler":
238 "__gcov_indirect_call_profiler_v2"),
239 ic_profiler_fn_type);
241 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
242 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
243 = tree_cons (get_identifier ("leaf"), NULL,
244 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
246 /* void (*) (gcov_type *, gcov_type, void *) */
247 time_profiler_fn_type
248 = build_function_type_list (void_type_node,
249 gcov_type_ptr, NULL_TREE);
250 tree_time_profiler_fn
251 = build_fn_decl ("__gcov_time_profiler",
252 time_profiler_fn_type);
253 TREE_NOTHROW (tree_time_profiler_fn) = 1;
254 DECL_ATTRIBUTES (tree_time_profiler_fn)
255 = tree_cons (get_identifier ("leaf"), NULL,
256 DECL_ATTRIBUTES (tree_time_profiler_fn));
258 /* void (*) (gcov_type *, gcov_type) */
259 average_profiler_fn_type
260 = build_function_type_list (void_type_node,
261 gcov_type_ptr, gcov_type_node, NULL_TREE);
262 tree_average_profiler_fn
263 = build_fn_decl ("__gcov_average_profiler",
264 average_profiler_fn_type);
265 TREE_NOTHROW (tree_average_profiler_fn) = 1;
266 DECL_ATTRIBUTES (tree_average_profiler_fn)
267 = tree_cons (get_identifier ("leaf"), NULL,
268 DECL_ATTRIBUTES (tree_average_profiler_fn));
269 tree_ior_profiler_fn
270 = build_fn_decl ("__gcov_ior_profiler",
271 average_profiler_fn_type);
272 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
273 DECL_ATTRIBUTES (tree_ior_profiler_fn)
274 = tree_cons (get_identifier ("leaf"), NULL,
275 DECL_ATTRIBUTES (tree_ior_profiler_fn));
277 /* LTO streamer needs assembler names. Because we create these decls
278 late, we need to initialize them by hand. */
279 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
280 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
281 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
282 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
283 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
284 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
285 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
289 /* Output instructions as GIMPLE trees to increment the edge
290 execution count, and insert them on E. We rely on
291 gsi_insert_on_edge to preserve the order. */
293 void
294 gimple_gen_edge_profiler (int edgeno, edge e)
296 tree ref, one, gcov_type_tmp_var;
297 gimple_assign stmt1, stmt2, stmt3;
299 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
300 one = build_int_cst (gcov_type_node, 1);
301 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
302 NULL, "PROF_edge_counter");
303 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
304 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
305 NULL, "PROF_edge_counter");
306 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
307 gimple_assign_lhs (stmt1), one);
308 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
309 gsi_insert_on_edge (e, stmt1);
310 gsi_insert_on_edge (e, stmt2);
311 gsi_insert_on_edge (e, stmt3);
314 /* Emits code to get VALUE to instrument at GSI, and returns the
315 variable containing the value. */
317 static tree
318 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
320 tree val = value->hvalue.value;
321 if (POINTER_TYPE_P (TREE_TYPE (val)))
322 val = fold_convert (build_nonstandard_integer_type
323 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
324 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
325 true, NULL_TREE, true, GSI_SAME_STMT);
328 /* Output instructions as GIMPLE trees to increment the interval histogram
329 counter. VALUE is the expression whose value is profiled. TAG is the
330 tag of the section for counters, BASE is offset of the counter position. */
332 void
333 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
335 gimple stmt = value->hvalue.stmt;
336 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
337 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
338 gimple_call call;
339 tree val;
340 tree start = build_int_cst_type (integer_type_node,
341 value->hdata.intvl.int_start);
342 tree steps = build_int_cst_type (unsigned_type_node,
343 value->hdata.intvl.steps);
345 ref_ptr = force_gimple_operand_gsi (&gsi,
346 build_addr (ref, current_function_decl),
347 true, NULL_TREE, true, GSI_SAME_STMT);
348 val = prepare_instrumented_value (&gsi, value);
349 call = gimple_build_call (tree_interval_profiler_fn, 4,
350 ref_ptr, val, start, steps);
351 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
354 /* Output instructions as GIMPLE trees to increment the power of two histogram
355 counter. VALUE is the expression whose value is profiled. TAG is the tag
356 of the section for counters, BASE is offset of the counter position. */
358 void
359 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
361 gimple stmt = value->hvalue.stmt;
362 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
363 tree ref_ptr = tree_coverage_counter_addr (tag, base);
364 gimple_call call;
365 tree val;
367 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
368 true, NULL_TREE, true, GSI_SAME_STMT);
369 val = prepare_instrumented_value (&gsi, value);
370 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
371 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
374 /* Output instructions as GIMPLE trees for code to find the most common value.
375 VALUE is the expression whose value is profiled. TAG is the tag of the
376 section for counters, BASE is offset of the counter position. */
378 void
379 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
381 gimple stmt = value->hvalue.stmt;
382 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
383 tree ref_ptr = tree_coverage_counter_addr (tag, base);
384 gimple_call call;
385 tree val;
387 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
388 true, NULL_TREE, true, GSI_SAME_STMT);
389 val = prepare_instrumented_value (&gsi, value);
390 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
391 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
395 /* Output instructions as GIMPLE trees for code to find the most
396 common called function in indirect call.
397 VALUE is the call expression whose indirect callee is profiled.
398 TAG is the tag of the section for counters, BASE is offset of the
399 counter position. */
401 void
402 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
404 tree tmp1;
405 gimple_assign stmt1, stmt2, stmt3;
406 gimple stmt = value->hvalue.stmt;
407 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
408 tree ref_ptr = tree_coverage_counter_addr (tag, base);
410 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
411 tag == GCOV_COUNTER_V_INDIR) ||
412 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
413 tag == GCOV_COUNTER_ICALL_TOPNV))
414 return;
416 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
417 true, NULL_TREE, true, GSI_SAME_STMT);
419 /* Insert code:
421 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
422 stmt2: tmp1 = (void *) (indirect call argument value)
423 stmt3: __gcov_indirect_call_callee = tmp1;
426 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
427 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
428 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
429 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
431 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
432 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
433 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
437 /* Output instructions as GIMPLE trees for code to find the most
438 common called function in indirect call. Insert instructions at the
439 beginning of every possible called function.
442 void
443 gimple_gen_ic_func_profiler (void)
445 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
446 gimple_stmt_iterator gsi;
447 gimple_call stmt1;
448 gimple_assign stmt2;
449 tree tree_uid, cur_func, void0;
451 if (c_node->only_called_directly_p ())
452 return;
454 gimple_init_edge_profiler ();
456 /* Insert code:
458 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
459 &current_function_decl)
461 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
463 cur_func = force_gimple_operand_gsi (&gsi,
464 build_addr (current_function_decl,
465 current_function_decl),
466 true, NULL_TREE,
467 true, GSI_SAME_STMT);
468 tree_uid = build_int_cst
469 (gcov_type_node, cgraph_node::get (current_function_decl)->profile_id);
470 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
471 if (flag_lto)
473 tree counter_ptr, ptr_var;
474 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
475 true, NULL_TREE, true,
476 GSI_SAME_STMT);
477 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
478 true, NULL_TREE, true,
479 GSI_SAME_STMT);
481 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
482 counter_ptr, tree_uid, cur_func, ptr_var);
484 else
486 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
487 tree_uid, cur_func);
489 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
491 /* Set __gcov_indirect_call_callee to 0,
492 so that calls from other modules won't get misattributed
493 to the last caller of the current callee. */
494 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
495 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
496 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
499 /* Output instructions as GIMPLE tree at the beginning for each function.
500 TAG is the tag of the section for counters, BASE is offset of the
501 counter position and GSI is the iterator we place the counter. */
503 void
504 gimple_gen_time_profiler (unsigned tag, unsigned base,
505 gimple_stmt_iterator &gsi)
507 tree ref_ptr = tree_coverage_counter_addr (tag, base);
508 gimple_call call;
510 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
511 true, NULL_TREE, true, GSI_SAME_STMT);
512 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
513 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
516 /* Output instructions as GIMPLE trees for code to find the most common value
517 of a difference between two evaluations of an expression.
518 VALUE is the expression whose value is profiled. TAG is the tag of the
519 section for counters, BASE is offset of the counter position. */
521 void
522 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
523 unsigned tag ATTRIBUTE_UNUSED,
524 unsigned base ATTRIBUTE_UNUSED)
526 /* FIXME implement this. */
527 #ifdef ENABLE_CHECKING
528 internal_error ("unimplemented functionality");
529 #endif
530 gcc_unreachable ();
533 /* Output instructions as GIMPLE trees to increment the average histogram
534 counter. VALUE is the expression whose value is profiled. TAG is the
535 tag of the section for counters, BASE is offset of the counter position. */
537 void
538 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
540 gimple stmt = value->hvalue.stmt;
541 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
542 tree ref_ptr = tree_coverage_counter_addr (tag, base);
543 gimple_call call;
544 tree val;
546 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
547 true, NULL_TREE,
548 true, GSI_SAME_STMT);
549 val = prepare_instrumented_value (&gsi, value);
550 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
551 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
554 /* Output instructions as GIMPLE trees to increment the ior histogram
555 counter. VALUE is the expression whose value is profiled. TAG is the
556 tag of the section for counters, BASE is offset of the counter position. */
558 void
559 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
561 gimple stmt = value->hvalue.stmt;
562 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
563 tree ref_ptr = tree_coverage_counter_addr (tag, base);
564 gimple_call call;
565 tree val;
567 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
568 true, NULL_TREE, true, GSI_SAME_STMT);
569 val = prepare_instrumented_value (&gsi, value);
570 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
571 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
574 /* Profile all functions in the callgraph. */
576 static unsigned int
577 tree_profiling (void)
579 struct cgraph_node *node;
581 /* This is a small-ipa pass that gets called only once, from
582 cgraphunit.c:ipa_passes(). */
583 gcc_assert (symtab->state == IPA_SSA);
585 init_node_map (true);
587 FOR_EACH_DEFINED_FUNCTION (node)
589 if (!gimple_has_body_p (node->decl))
590 continue;
592 /* Don't profile functions produced for builtin stuff. */
593 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
594 continue;
596 /* Do not instrument extern inline functions when testing coverage.
597 While this is not perfectly consistent (early inlined extern inlines
598 will get acocunted), testsuite expects that. */
599 if (DECL_EXTERNAL (node->decl)
600 && flag_test_coverage)
601 continue;
603 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
605 /* Local pure-const may imply need to fixup the cfg. */
606 if (execute_fixup_cfg () & TODO_cleanup_cfg)
607 cleanup_tree_cfg ();
609 branch_prob ();
611 if (! flag_branch_probabilities
612 && flag_profile_values)
613 gimple_gen_ic_func_profiler ();
615 if (flag_branch_probabilities
616 && flag_profile_values
617 && flag_value_profile_transformations)
618 gimple_value_profile_transformations ();
620 /* The above could hose dominator info. Currently there is
621 none coming in, this is a safety valve. It should be
622 easy to adjust it, if and when there is some. */
623 free_dominance_info (CDI_DOMINATORS);
624 free_dominance_info (CDI_POST_DOMINATORS);
625 pop_cfun ();
628 /* Drop pure/const flags from instrumented functions. */
629 FOR_EACH_DEFINED_FUNCTION (node)
631 if (!gimple_has_body_p (node->decl)
632 || !(!node->clone_of
633 || node->decl != node->clone_of->decl))
634 continue;
636 /* Don't profile functions produced for builtin stuff. */
637 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
638 continue;
640 node->set_const_flag (false, false);
641 node->set_pure_flag (false, false);
644 /* Update call statements and rebuild the cgraph. */
645 FOR_EACH_DEFINED_FUNCTION (node)
647 basic_block bb;
649 if (!gimple_has_body_p (node->decl)
650 || !(!node->clone_of
651 || node->decl != node->clone_of->decl))
652 continue;
654 /* Don't profile functions produced for builtin stuff. */
655 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
656 continue;
658 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
660 FOR_EACH_BB_FN (bb, cfun)
662 gimple_stmt_iterator gsi;
663 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
665 gimple stmt = gsi_stmt (gsi);
666 if (is_gimple_call (stmt))
667 update_stmt (stmt);
671 /* re-merge split blocks. */
672 cleanup_tree_cfg ();
673 update_ssa (TODO_update_ssa);
675 cgraph_edge::rebuild_edges ();
677 pop_cfun ();
680 handle_missing_profiles ();
682 del_node_map ();
683 return 0;
686 namespace {
688 const pass_data pass_data_ipa_tree_profile =
690 SIMPLE_IPA_PASS, /* type */
691 "profile", /* name */
692 OPTGROUP_NONE, /* optinfo_flags */
693 TV_IPA_PROFILE, /* tv_id */
694 0, /* properties_required */
695 0, /* properties_provided */
696 0, /* properties_destroyed */
697 0, /* todo_flags_start */
698 0, /* todo_flags_finish */
701 class pass_ipa_tree_profile : public simple_ipa_opt_pass
703 public:
704 pass_ipa_tree_profile (gcc::context *ctxt)
705 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
708 /* opt_pass methods: */
709 virtual bool gate (function *);
710 virtual unsigned int execute (function *) { return tree_profiling (); }
712 }; // class pass_ipa_tree_profile
714 bool
715 pass_ipa_tree_profile::gate (function *)
717 /* When profile instrumentation, use or test coverage shall be performed. */
718 return (!in_lto_p
719 && (flag_branch_probabilities || flag_test_coverage
720 || profile_arc_flag));
723 } // anon namespace
725 simple_ipa_opt_pass *
726 make_pass_ipa_tree_profile (gcc::context *ctxt)
728 return new pass_ipa_tree_profile (ctxt);
731 #include "gt-tree-profile.h"