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