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