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