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