calls.c (store_one_arg): Remove incorrect const qualification on the type of the...
[gcc.git] / gcc / tree-profile.c
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.
7
8 This file is part of GCC.
9
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.
14
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.
19
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/>. */
23
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.c for overview. */
26
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
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;
68
69
70 static GTY(()) tree ic_void_ptr_var;
71 static GTY(()) tree ic_gcov_type_ptr_var;
72 static GTY(()) tree ptr_void;
73
74 /* Do initialization work for the edge profiler. */
75
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
80 */
81 static void
82 init_ic_make_global_vars (void)
83 {
84 tree gcov_type_ptr;
85
86 ptr_void = build_pointer_type (void_type_node);
87
88 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
89 if (flag_lto)
90 {
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;
99 }
100 else
101 {
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;
108 }
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);
115
116 varpool_finalize_decl (ic_void_ptr_var);
117
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)
121 {
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;
130 }
131 else
132 {
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;
139 }
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);
146
147 varpool_finalize_decl (ic_gcov_type_ptr_var);
148 }
149
150 /* Create the type and function decls for the interface with gcov. */
151
152 void
153 gimple_init_edge_profiler (void)
154 {
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;
162
163 if (!gcov_type_node)
164 {
165 gcov_type_node = get_gcov_type ();
166 gcov_type_ptr = build_pointer_type (gcov_type_node);
167
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));
181
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));
193
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));
206
207 init_ic_make_global_vars ();
208
209 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
210 if (flag_lto)
211 {
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);
221 }
222 else
223 {
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);
233 }
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));
238
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));
250
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));
269
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);
279 }
280 }
281
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. */
285
286 void
287 gimple_gen_edge_profiler (int edgeno, edge e)
288 {
289 tree ref, one, gcov_type_tmp_var;
290 gimple stmt1, stmt2, stmt3;
291
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);
305 }
306
307 /* Emits code to get VALUE to instrument at GSI, and returns the
308 variable containing the value. */
309
310 static tree
311 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
312 {
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);
319 }
320
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. */
324
325 void
326 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
327 {
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);
337
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);
345 }
346
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. */
350
351 void
352 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
353 {
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;
359
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);
365 }
366
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. */
370
371 void
372 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
373 {
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;
379
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);
385 }
386
387
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. */
393
394 void
395 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
396 {
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);
402
403 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
404 true, NULL_TREE, true, GSI_SAME_STMT);
405
406 /* Insert code:
407
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;
411 */
412
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));
417
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);
421 }
422
423
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.
427 */
428
429 void
430 gimple_gen_ic_func_profiler (void)
431 {
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;
436
437 if (cgraph_only_called_directly_p (c_node))
438 return;
439
440 gimple_init_edge_profiler ();
441
442 /* Insert code:
443
444 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
445 &current_function_decl)
446 */
447 gsi =
448 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
449
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)
459 {
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);
467
468 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
469 counter_ptr, tree_uid, cur_func, ptr_var);
470 }
471 else
472 {
473 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
474 tree_uid, cur_func);
475 }
476 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
477
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);
484 }
485
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. */
489
490 void
491 gimple_gen_time_profiler (unsigned tag, unsigned base,
492 gimple_stmt_iterator &gsi)
493 {
494 tree ref_ptr = tree_coverage_counter_addr (tag, base);
495 gimple call;
496
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);
501 }
502
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. */
507
508 void
509 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
510 unsigned tag ATTRIBUTE_UNUSED,
511 unsigned base ATTRIBUTE_UNUSED)
512 {
513 /* FIXME implement this. */
514 #ifdef ENABLE_CHECKING
515 internal_error ("unimplemented functionality");
516 #endif
517 gcc_unreachable ();
518 }
519
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. */
523
524 void
525 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
526 {
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;
532
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);
539 }
540
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. */
544
545 void
546 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
547 {
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;
553
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);
559 }
560
561 /* Profile all functions in the callgraph. */
562
563 static unsigned int
564 tree_profiling (void)
565 {
566 struct cgraph_node *node;
567
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);
571
572 init_node_map (true);
573
574 FOR_EACH_DEFINED_FUNCTION (node)
575 {
576 if (!gimple_has_body_p (node->decl))
577 continue;
578
579 /* Don't profile functions produced for builtin stuff. */
580 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
581 continue;
582
583 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
584
585 /* Local pure-const may imply need to fixup the cfg. */
586 if (execute_fixup_cfg () & TODO_cleanup_cfg)
587 cleanup_tree_cfg ();
588
589 branch_prob ();
590
591 if (! flag_branch_probabilities
592 && flag_profile_values)
593 gimple_gen_ic_func_profiler ();
594
595 if (flag_branch_probabilities
596 && flag_profile_values
597 && flag_value_profile_transformations)
598 gimple_value_profile_transformations ();
599
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 ();
606 }
607
608 /* Drop pure/const flags from instrumented functions. */
609 FOR_EACH_DEFINED_FUNCTION (node)
610 {
611 if (!gimple_has_body_p (node->decl)
612 || !(!node->clone_of
613 || node->decl != node->clone_of->decl))
614 continue;
615
616 /* Don't profile functions produced for builtin stuff. */
617 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
618 continue;
619
620 cgraph_set_const_flag (node, false, false);
621 cgraph_set_pure_flag (node, false, false);
622 }
623
624 /* Update call statements and rebuild the cgraph. */
625 FOR_EACH_DEFINED_FUNCTION (node)
626 {
627 basic_block bb;
628
629 if (!gimple_has_body_p (node->decl)
630 || !(!node->clone_of
631 || node->decl != node->clone_of->decl))
632 continue;
633
634 /* Don't profile functions produced for builtin stuff. */
635 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
636 continue;
637
638 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
639
640 FOR_EACH_BB_FN (bb, cfun)
641 {
642 gimple_stmt_iterator gsi;
643 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
644 {
645 gimple stmt = gsi_stmt (gsi);
646 if (is_gimple_call (stmt))
647 update_stmt (stmt);
648 }
649 }
650
651 /* re-merge split blocks. */
652 cleanup_tree_cfg ();
653 update_ssa (TODO_update_ssa);
654
655 rebuild_cgraph_edges ();
656
657 pop_cfun ();
658 }
659
660 handle_missing_profiles ();
661
662 del_node_map ();
663 return 0;
664 }
665
666 /* When profile instrumentation, use or test coverage shall be performed. */
667
668 static bool
669 gate_tree_profile_ipa (void)
670 {
671 return (!in_lto_p
672 && (flag_branch_probabilities || flag_test_coverage
673 || profile_arc_flag));
674 }
675
676 namespace {
677
678 const pass_data pass_data_ipa_tree_profile =
679 {
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 */
691 };
692
693 class pass_ipa_tree_profile : public simple_ipa_opt_pass
694 {
695 public:
696 pass_ipa_tree_profile (gcc::context *ctxt)
697 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
698 {}
699
700 /* opt_pass methods: */
701 bool gate () { return gate_tree_profile_ipa (); }
702 unsigned int execute () { return tree_profiling (); }
703
704 }; // class pass_ipa_tree_profile
705
706 } // anon namespace
707
708 simple_ipa_opt_pass *
709 make_pass_ipa_tree_profile (gcc::context *ctxt)
710 {
711 return new pass_ipa_tree_profile (ctxt);
712 }
713
714 #include "gt-tree-profile.h"