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