dfd0ef0467735ed9ea819f9712f3fead789a31bf
[gcc.git] / gcc / tree-profile.c
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4 Free Software Foundation, Inc.
5 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6 based on some ideas from Dain Samples of UC Berkeley.
7 Further mangling by Bob Manson, Cygnus Support.
8 Converted to use trees by Dale Johannesen, Apple Computer.
9
10 This file is part of GCC.
11
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
15 version.
16
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
25
26 /* Generate basic block profile instrumentation and auxiliary files.
27 Tree-based version. See profile.c for overview. */
28
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "basic-block.h"
36 #include "diagnostic-core.h"
37 #include "coverage.h"
38 #include "tree.h"
39 #include "tree-flow.h"
40 #include "tree-dump.h"
41 #include "tree-pass.h"
42 #include "timevar.h"
43 #include "value-prof.h"
44 #include "cgraph.h"
45 #include "profile.h"
46 #include "target.h"
47
48 static GTY(()) tree gcov_type_node;
49 static GTY(()) tree gcov_type_tmp_var;
50 static GTY(()) tree tree_interval_profiler_fn;
51 static GTY(()) tree tree_pow2_profiler_fn;
52 static GTY(()) tree tree_one_value_profiler_fn;
53 static GTY(()) tree tree_indirect_call_profiler_fn;
54 static GTY(()) tree tree_average_profiler_fn;
55 static GTY(()) tree tree_ior_profiler_fn;
56 \f
57
58 static GTY(()) tree ic_void_ptr_var;
59 static GTY(()) tree ic_gcov_type_ptr_var;
60 static GTY(()) tree ptr_void;
61
62 /* Do initialization work for the edge profiler. */
63
64 /* Add code:
65 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
66 static void* __gcov_indirect_call_callee; // actual callee address
67 */
68 static void
69 init_ic_make_global_vars (void)
70 {
71 tree gcov_type_ptr;
72
73 ptr_void = build_pointer_type (void_type_node);
74
75 ic_void_ptr_var
76 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
77 get_identifier ("__gcov_indirect_call_callee"),
78 ptr_void);
79 TREE_STATIC (ic_void_ptr_var) = 1;
80 TREE_PUBLIC (ic_void_ptr_var) = 0;
81 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
82 DECL_INITIAL (ic_void_ptr_var) = NULL;
83 if (targetm.have_tls)
84 DECL_TLS_MODEL (ic_void_ptr_var) =
85 decl_default_tls_model (ic_void_ptr_var);
86
87 varpool_finalize_decl (ic_void_ptr_var);
88
89 gcov_type_ptr = build_pointer_type (get_gcov_type ());
90 ic_gcov_type_ptr_var
91 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
92 get_identifier ("__gcov_indirect_call_counters"),
93 gcov_type_ptr);
94 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
95 TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
96 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
97 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
98 if (targetm.have_tls)
99 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
100 decl_default_tls_model (ic_gcov_type_ptr_var);
101
102 varpool_finalize_decl (ic_gcov_type_ptr_var);
103 }
104
105 void
106 gimple_init_edge_profiler (void)
107 {
108 tree interval_profiler_fn_type;
109 tree pow2_profiler_fn_type;
110 tree one_value_profiler_fn_type;
111 tree gcov_type_ptr;
112 tree ic_profiler_fn_type;
113 tree average_profiler_fn_type;
114
115 if (!gcov_type_node)
116 {
117 gcov_type_node = get_gcov_type ();
118 gcov_type_ptr = build_pointer_type (gcov_type_node);
119
120 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
121 interval_profiler_fn_type
122 = build_function_type_list (void_type_node,
123 gcov_type_ptr, gcov_type_node,
124 integer_type_node,
125 unsigned_type_node, NULL_TREE);
126 tree_interval_profiler_fn
127 = build_fn_decl ("__gcov_interval_profiler",
128 interval_profiler_fn_type);
129 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
130 DECL_ATTRIBUTES (tree_interval_profiler_fn)
131 = tree_cons (get_identifier ("leaf"), NULL,
132 DECL_ATTRIBUTES (tree_interval_profiler_fn));
133
134 /* void (*) (gcov_type *, gcov_type) */
135 pow2_profiler_fn_type
136 = build_function_type_list (void_type_node,
137 gcov_type_ptr, gcov_type_node,
138 NULL_TREE);
139 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
140 pow2_profiler_fn_type);
141 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
142 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
143 = tree_cons (get_identifier ("leaf"), NULL,
144 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
145
146 /* void (*) (gcov_type *, gcov_type) */
147 one_value_profiler_fn_type
148 = build_function_type_list (void_type_node,
149 gcov_type_ptr, gcov_type_node,
150 NULL_TREE);
151 tree_one_value_profiler_fn
152 = build_fn_decl ("__gcov_one_value_profiler",
153 one_value_profiler_fn_type);
154 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
155 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
156 = tree_cons (get_identifier ("leaf"), NULL,
157 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
158
159 init_ic_make_global_vars ();
160
161 /* void (*) (gcov_type *, gcov_type, void *, void *) */
162 ic_profiler_fn_type
163 = build_function_type_list (void_type_node,
164 gcov_type_ptr, gcov_type_node,
165 ptr_void,
166 ptr_void, NULL_TREE);
167 tree_indirect_call_profiler_fn
168 = build_fn_decl ("__gcov_indirect_call_profiler",
169 ic_profiler_fn_type);
170 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
171 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
172 = tree_cons (get_identifier ("leaf"), NULL,
173 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
174
175 /* void (*) (gcov_type *, gcov_type) */
176 average_profiler_fn_type
177 = build_function_type_list (void_type_node,
178 gcov_type_ptr, gcov_type_node, NULL_TREE);
179 tree_average_profiler_fn
180 = build_fn_decl ("__gcov_average_profiler",
181 average_profiler_fn_type);
182 TREE_NOTHROW (tree_average_profiler_fn) = 1;
183 DECL_ATTRIBUTES (tree_average_profiler_fn)
184 = tree_cons (get_identifier ("leaf"), NULL,
185 DECL_ATTRIBUTES (tree_average_profiler_fn));
186 tree_ior_profiler_fn
187 = build_fn_decl ("__gcov_ior_profiler",
188 average_profiler_fn_type);
189 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
190 DECL_ATTRIBUTES (tree_ior_profiler_fn)
191 = tree_cons (get_identifier ("leaf"), NULL,
192 DECL_ATTRIBUTES (tree_ior_profiler_fn));
193
194 /* LTO streamer needs assembler names. Because we create these decls
195 late, we need to initialize them by hand. */
196 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
197 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
198 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
199 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
200 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
201 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
202 }
203 }
204
205 /* Output instructions as GIMPLE trees to increment the edge
206 execution count, and insert them on E. We rely on
207 gsi_insert_on_edge to preserve the order. */
208
209 void
210 gimple_gen_edge_profiler (int edgeno, edge e)
211 {
212 tree ref, one;
213 gimple stmt1, stmt2, stmt3;
214
215 /* We share one temporary variable declaration per function. This
216 gets re-set in tree_profiling. */
217 if (gcov_type_tmp_var == NULL_TREE)
218 gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter");
219 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
220 one = build_int_cst (gcov_type_node, 1);
221 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
222 gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1));
223 find_referenced_vars_in (stmt1);
224 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
225 gimple_assign_lhs (stmt1), one);
226 gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2));
227 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
228 gsi_insert_on_edge (e, stmt1);
229 gsi_insert_on_edge (e, stmt2);
230 gsi_insert_on_edge (e, stmt3);
231 }
232
233 /* Emits code to get VALUE to instrument at GSI, and returns the
234 variable containing the value. */
235
236 static tree
237 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
238 {
239 tree val = value->hvalue.value;
240 if (POINTER_TYPE_P (TREE_TYPE (val)))
241 val = fold_convert (build_nonstandard_integer_type
242 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
243 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
244 true, NULL_TREE, true, GSI_SAME_STMT);
245 }
246
247 /* Output instructions as GIMPLE trees to increment the interval histogram
248 counter. VALUE is the expression whose value is profiled. TAG is the
249 tag of the section for counters, BASE is offset of the counter position. */
250
251 void
252 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
253 {
254 gimple stmt = value->hvalue.stmt;
255 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
256 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
257 gimple call;
258 tree val;
259 tree start = build_int_cst_type (integer_type_node,
260 value->hdata.intvl.int_start);
261 tree steps = build_int_cst_type (unsigned_type_node,
262 value->hdata.intvl.steps);
263
264 ref_ptr = force_gimple_operand_gsi (&gsi,
265 build_addr (ref, current_function_decl),
266 true, NULL_TREE, true, GSI_SAME_STMT);
267 val = prepare_instrumented_value (&gsi, value);
268 call = gimple_build_call (tree_interval_profiler_fn, 4,
269 ref_ptr, val, start, steps);
270 find_referenced_vars_in (call);
271 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
272 }
273
274 /* Output instructions as GIMPLE trees to increment the power of two histogram
275 counter. VALUE is the expression whose value is profiled. TAG is the tag
276 of the section for counters, BASE is offset of the counter position. */
277
278 void
279 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
280 {
281 gimple stmt = value->hvalue.stmt;
282 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
283 tree ref_ptr = tree_coverage_counter_addr (tag, base);
284 gimple call;
285 tree val;
286
287 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
288 true, NULL_TREE, true, GSI_SAME_STMT);
289 val = prepare_instrumented_value (&gsi, value);
290 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
291 find_referenced_vars_in (call);
292 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
293 }
294
295 /* Output instructions as GIMPLE trees for code to find the most common value.
296 VALUE is the expression whose value is profiled. TAG is the tag of the
297 section for counters, BASE is offset of the counter position. */
298
299 void
300 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
301 {
302 gimple stmt = value->hvalue.stmt;
303 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
304 tree ref_ptr = tree_coverage_counter_addr (tag, base);
305 gimple call;
306 tree val;
307
308 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
309 true, NULL_TREE, true, GSI_SAME_STMT);
310 val = prepare_instrumented_value (&gsi, value);
311 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
312 find_referenced_vars_in (call);
313 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
314 }
315
316
317 /* Output instructions as GIMPLE trees for code to find the most
318 common called function in indirect call.
319 VALUE is the call expression whose indirect callee is profiled.
320 TAG is the tag of the section for counters, BASE is offset of the
321 counter position. */
322
323 void
324 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
325 {
326 tree tmp1;
327 gimple stmt1, stmt2, stmt3;
328 gimple stmt = value->hvalue.stmt;
329 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
330 tree ref_ptr = tree_coverage_counter_addr (tag, base);
331
332 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
333 true, NULL_TREE, true, GSI_SAME_STMT);
334
335 /* Insert code:
336
337 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
338 __gcov_indirect_call_callee = (void *) indirect call argument;
339 */
340
341 tmp1 = create_tmp_reg (ptr_void, "PROF");
342 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
343 find_referenced_vars_in (stmt1);
344 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
345 gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2));
346 find_referenced_vars_in (stmt2);
347 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
348
349 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
350 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
351 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
352 }
353
354
355 /* Output instructions as GIMPLE trees for code to find the most
356 common called function in indirect call. Insert instructions at the
357 beginning of every possible called function.
358 */
359
360 void
361 gimple_gen_ic_func_profiler (void)
362 {
363 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
364 gimple_stmt_iterator gsi;
365 gimple stmt1, stmt2;
366 tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
367
368 if (cgraph_only_called_directly_p (c_node))
369 return;
370
371 gimple_init_edge_profiler ();
372
373 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
374
375 cur_func = force_gimple_operand_gsi (&gsi,
376 build_addr (current_function_decl,
377 current_function_decl),
378 true, NULL_TREE,
379 true, GSI_SAME_STMT);
380 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
381 true, NULL_TREE, true,
382 GSI_SAME_STMT);
383 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
384 true, NULL_TREE, true,
385 GSI_SAME_STMT);
386 tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
387 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
388 counter_ptr, tree_uid, cur_func, ptr_var);
389 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
390
391 /* Set __gcov_indirect_call_callee to 0,
392 so that calls from other modules won't get misattributed
393 to the last caller of the current callee. */
394 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
395 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
396 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
397 }
398
399 /* Output instructions as GIMPLE trees for code to find the most common value
400 of a difference between two evaluations of an expression.
401 VALUE is the expression whose value is profiled. TAG is the tag of the
402 section for counters, BASE is offset of the counter position. */
403
404 void
405 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
406 unsigned tag ATTRIBUTE_UNUSED,
407 unsigned base ATTRIBUTE_UNUSED)
408 {
409 /* FIXME implement this. */
410 #ifdef ENABLE_CHECKING
411 internal_error ("unimplemented functionality");
412 #endif
413 gcc_unreachable ();
414 }
415
416 /* Output instructions as GIMPLE trees to increment the average histogram
417 counter. VALUE is the expression whose value is profiled. TAG is the
418 tag of the section for counters, BASE is offset of the counter position. */
419
420 void
421 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
422 {
423 gimple stmt = value->hvalue.stmt;
424 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
425 tree ref_ptr = tree_coverage_counter_addr (tag, base);
426 gimple call;
427 tree val;
428
429 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
430 true, NULL_TREE,
431 true, GSI_SAME_STMT);
432 val = prepare_instrumented_value (&gsi, value);
433 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
434 find_referenced_vars_in (call);
435 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
436 }
437
438 /* Output instructions as GIMPLE trees to increment the ior histogram
439 counter. VALUE is the expression whose value is profiled. TAG is the
440 tag of the section for counters, BASE is offset of the counter position. */
441
442 void
443 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
444 {
445 gimple stmt = value->hvalue.stmt;
446 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
447 tree ref_ptr = tree_coverage_counter_addr (tag, base);
448 gimple call;
449 tree val;
450
451 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
452 true, NULL_TREE, true, GSI_SAME_STMT);
453 val = prepare_instrumented_value (&gsi, value);
454 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
455 find_referenced_vars_in (call);
456 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
457 }
458
459 /* Profile all functions in the callgraph. */
460
461 static unsigned int
462 tree_profiling (void)
463 {
464 struct cgraph_node *node;
465
466 /* Don't profile functions produced at destruction time, particularly
467 the gcov datastructure initializer. Don't profile if it has been
468 already instrumented either (when OpenMP expansion creates
469 child function from already instrumented body). */
470 if (cgraph_state == CGRAPH_STATE_FINISHED)
471 return 0;
472
473 init_node_map();
474
475 FOR_EACH_DEFINED_FUNCTION (node)
476 {
477 if (!gimple_has_body_p (node->symbol.decl))
478 continue;
479
480 /* Don't profile functions produced for builtin stuff. */
481 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
482 || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
483 continue;
484
485 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
486 current_function_decl = node->symbol.decl;
487
488 /* Re-set global shared temporary variable for edge-counters. */
489 gcov_type_tmp_var = NULL_TREE;
490
491 /* Local pure-const may imply need to fixup the cfg. */
492 if (execute_fixup_cfg () & TODO_cleanup_cfg)
493 cleanup_tree_cfg ();
494 branch_prob ();
495
496 if (! flag_branch_probabilities
497 && flag_profile_values)
498 gimple_gen_ic_func_profiler ();
499
500 if (flag_branch_probabilities
501 && flag_profile_values
502 && flag_value_profile_transformations)
503 gimple_value_profile_transformations ();
504
505 /* The above could hose dominator info. Currently there is
506 none coming in, this is a safety valve. It should be
507 easy to adjust it, if and when there is some. */
508 free_dominance_info (CDI_DOMINATORS);
509 free_dominance_info (CDI_POST_DOMINATORS);
510
511 current_function_decl = NULL;
512 pop_cfun ();
513 }
514
515 /* Drop pure/const flags from instrumented functions. */
516 FOR_EACH_DEFINED_FUNCTION (node)
517 {
518 if (!gimple_has_body_p (node->symbol.decl)
519 || !(!node->clone_of
520 || node->symbol.decl != node->clone_of->symbol.decl))
521 continue;
522
523 /* Don't profile functions produced for builtin stuff. */
524 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
525 || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
526 continue;
527
528 cgraph_set_const_flag (node, false, false);
529 cgraph_set_pure_flag (node, false, false);
530 }
531
532 /* Update call statements and rebuild the cgraph. */
533 FOR_EACH_DEFINED_FUNCTION (node)
534 {
535 basic_block bb;
536
537 if (!gimple_has_body_p (node->symbol.decl)
538 || !(!node->clone_of
539 || node->symbol.decl != node->clone_of->symbol.decl))
540 continue;
541
542 /* Don't profile functions produced for builtin stuff. */
543 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
544 || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
545 continue;
546
547 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
548 current_function_decl = node->symbol.decl;
549
550 FOR_EACH_BB (bb)
551 {
552 gimple_stmt_iterator gsi;
553 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
554 {
555 gimple stmt = gsi_stmt (gsi);
556 if (is_gimple_call (stmt))
557 update_stmt (stmt);
558 }
559 }
560
561 cfun->after_tree_profile = 1;
562 update_ssa (TODO_update_ssa);
563
564 rebuild_cgraph_edges ();
565
566 current_function_decl = NULL;
567 pop_cfun ();
568 }
569
570 del_node_map();
571 return 0;
572 }
573
574 /* When profile instrumentation, use or test coverage shall be performed. */
575
576 static bool
577 gate_tree_profile_ipa (void)
578 {
579 return (!in_lto_p
580 && (flag_branch_probabilities || flag_test_coverage
581 || profile_arc_flag));
582 }
583
584 struct simple_ipa_opt_pass pass_ipa_tree_profile =
585 {
586 {
587 SIMPLE_IPA_PASS,
588 "profile", /* name */
589 gate_tree_profile_ipa, /* gate */
590 tree_profiling, /* execute */
591 NULL, /* sub */
592 NULL, /* next */
593 0, /* static_pass_number */
594 TV_IPA_PROFILE, /* tv_id */
595 0, /* properties_required */
596 0, /* properties_provided */
597 0, /* properties_destroyed */
598 0, /* todo_flags_start */
599 0 /* todo_flags_finish */
600 }
601 };
602
603 #include "gt-tree-profile.h"