]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-profile.c
* output.h (__gcc_host_wide_int__): Move to hwint.h.
[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"
40#include "tree-dump.h"
41#include "tree-pass.h"
42#include "timevar.h"
43#include "value-prof.h"
167b550b 44#include "cgraph.h"
1ad3e14c 45#include "profile.h"
109cfbe4 46#include "target.h"
4ee9c684 47
d7683f13 48static GTY(()) tree gcov_type_node;
f81207a7 49static GTY(()) tree gcov_type_tmp_var;
d7683f13 50static GTY(()) tree tree_interval_profiler_fn;
51static GTY(()) tree tree_pow2_profiler_fn;
52static GTY(()) tree tree_one_value_profiler_fn;
167b550b 53static GTY(()) tree tree_indirect_call_profiler_fn;
162719b3 54static GTY(()) tree tree_average_profiler_fn;
55static GTY(()) tree tree_ior_profiler_fn;
4ee9c684 56\f
4b0a9554 57
167b550b 58static GTY(()) tree ic_void_ptr_var;
59static GTY(()) tree ic_gcov_type_ptr_var;
60static GTY(()) tree ptr_void;
61
4b0a9554 62/* Do initialization work for the edge profiler. */
63
167b550b 64/* Add code:
65 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
f0b5f617 66 static void* __gcov_indirect_call_callee; // actual callee address
167b550b 67*/
68static void
fc49fbc1 69init_ic_make_global_vars (void)
167b550b 70{
71 tree gcov_type_ptr;
72
73 ptr_void = build_pointer_type (void_type_node);
48e1416a 74
75 ic_void_ptr_var
76 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
77 get_identifier ("__gcov_indirect_call_callee"),
167b550b 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;
109cfbe4 83 if (targetm.have_tls)
84 DECL_TLS_MODEL (ic_void_ptr_var) =
85 decl_default_tls_model (ic_void_ptr_var);
86
6c0782b1 87 varpool_finalize_decl (ic_void_ptr_var);
167b550b 88
89 gcov_type_ptr = build_pointer_type (get_gcov_type ());
48e1416a 90 ic_gcov_type_ptr_var
91 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
92 get_identifier ("__gcov_indirect_call_counters"),
167b550b 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;
109cfbe4 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
6c0782b1 102 varpool_finalize_decl (ic_gcov_type_ptr_var);
167b550b 103}
104
fc49fbc1 105void
106gimple_init_edge_profiler (void)
4b0a9554 107{
d7683f13 108 tree interval_profiler_fn_type;
109 tree pow2_profiler_fn_type;
110 tree one_value_profiler_fn_type;
111 tree gcov_type_ptr;
167b550b 112 tree ic_profiler_fn_type;
162719b3 113 tree average_profiler_fn_type;
d7683f13 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);
85344eeb 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));
d7683f13 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);
85344eeb 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));
d7683f13 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);
85344eeb 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));
167b550b 158
fc49fbc1 159 init_ic_make_global_vars ();
48e1416a 160
167b550b 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);
85344eeb 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
162719b3 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);
85344eeb 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));
162719b3 186 tree_ior_profiler_fn
187 = build_fn_decl ("__gcov_ior_profiler",
188 average_profiler_fn_type);
85344eeb 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
6c0782b1 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);
d7683f13 202 }
4b0a9554 203}
204
48e1416a 205/* Output instructions as GIMPLE trees to increment the edge
206 execution count, and insert them on E. We rely on
75a70cf9 207 gsi_insert_on_edge to preserve the order. */
4ee9c684 208
fc49fbc1 209void
210gimple_gen_edge_profiler (int edgeno, edge e)
4ee9c684 211{
75a70cf9 212 tree ref, one;
213 gimple stmt1, stmt2, stmt3;
f81207a7 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)
85344eeb 218 gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter");
f81207a7 219 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
220 one = build_int_cst (gcov_type_node, 1);
75a70cf9 221 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
85344eeb 222 gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1));
6d3d8bf0 223 find_referenced_vars_in (stmt1);
75a70cf9 224 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
85344eeb 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));
75a70cf9 228 gsi_insert_on_edge (e, stmt1);
229 gsi_insert_on_edge (e, stmt2);
230 gsi_insert_on_edge (e, stmt3);
4ee9c684 231}
232
75a70cf9 233/* Emits code to get VALUE to instrument at GSI, and returns the
d7683f13 234 variable containing the value. */
235
236static tree
75a70cf9 237prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
d7683f13 238{
ed4294da 239 tree val = value->hvalue.value;
c821ef7d 240 if (POINTER_TYPE_P (TREE_TYPE (val)))
a0553bff 241 val = fold_convert (build_nonstandard_integer_type
242 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
75a70cf9 243 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
244 true, NULL_TREE, true, GSI_SAME_STMT);
d7683f13 245}
246
48e1416a 247/* Output instructions as GIMPLE trees to increment the interval histogram
248 counter. VALUE is the expression whose value is profiled. TAG is the
4ee9c684 249 tag of the section for counters, BASE is offset of the counter position. */
250
fc49fbc1 251void
252gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
4ee9c684 253{
75a70cf9 254 gimple stmt = value->hvalue.stmt;
255 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
d7683f13 256 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
75a70cf9 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);
48e1416a 263
75a70cf9 264 ref_ptr = force_gimple_operand_gsi (&gsi,
d2024a0d 265 build_addr (ref, current_function_decl),
75a70cf9 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);
6d3d8bf0 270 find_referenced_vars_in (call);
77fca8b5 271 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
4ee9c684 272}
273
48e1416a 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
4ee9c684 276 of the section for counters, BASE is offset of the counter position. */
277
fc49fbc1 278void
279gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
4ee9c684 280{
75a70cf9 281 gimple stmt = value->hvalue.stmt;
282 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
a961cdc2 283 tree ref_ptr = tree_coverage_counter_addr (tag, base);
75a70cf9 284 gimple call;
285 tree val;
48e1416a 286
75a70cf9 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);
6d3d8bf0 291 find_referenced_vars_in (call);
77fca8b5 292 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
4ee9c684 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
fc49fbc1 299void
300gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
4ee9c684 301{
75a70cf9 302 gimple stmt = value->hvalue.stmt;
303 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
a961cdc2 304 tree ref_ptr = tree_coverage_counter_addr (tag, base);
75a70cf9 305 gimple call;
306 tree val;
48e1416a 307
75a70cf9 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);
6d3d8bf0 312 find_referenced_vars_in (call);
77fca8b5 313 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
4ee9c684 314}
315
167b550b 316
317/* Output instructions as GIMPLE trees for code to find the most
48e1416a 318 common called function in indirect call.
0d424440 319 VALUE is the call expression whose indirect callee is profiled.
167b550b 320 TAG is the tag of the section for counters, BASE is offset of the
321 counter position. */
322
fc49fbc1 323void
324gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
167b550b 325{
75a70cf9 326 tree tmp1;
327 gimple stmt1, stmt2, stmt3;
328 gimple stmt = value->hvalue.stmt;
329 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
a961cdc2 330 tree ref_ptr = tree_coverage_counter_addr (tag, base);
167b550b 331
75a70cf9 332 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
333 true, NULL_TREE, true, GSI_SAME_STMT);
167b550b 334
335 /* Insert code:
48e1416a 336
337 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
167b550b 338 __gcov_indirect_call_callee = (void *) indirect call argument;
339 */
340
85344eeb 341 tmp1 = create_tmp_reg (ptr_void, "PROF");
75a70cf9 342 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
6d3d8bf0 343 find_referenced_vars_in (stmt1);
75a70cf9 344 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
85344eeb 345 gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2));
6d3d8bf0 346 find_referenced_vars_in (stmt2);
85344eeb 347 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
167b550b 348
75a70cf9 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);
167b550b 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
0d424440 357 beginning of every possible called function.
167b550b 358 */
359
fc49fbc1 360void
361gimple_gen_ic_func_profiler (void)
167b550b 362{
fd6a3c41 363 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
75a70cf9 364 gimple_stmt_iterator gsi;
75a70cf9 365 gimple stmt1, stmt2;
85344eeb 366 tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
167b550b 367
cdedc740 368 if (cgraph_only_called_directly_p (c_node))
6329636b 369 return;
48e1416a 370
fc49fbc1 371 gimple_init_edge_profiler ();
48e1416a 372
85344eeb 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);
1ad3e14c 386 tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
85344eeb 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);
167b550b 397}
398
48e1416a 399/* Output instructions as GIMPLE trees for code to find the most common value
4ee9c684 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
fc49fbc1 404void
405gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
75a70cf9 406 unsigned tag ATTRIBUTE_UNUSED,
407 unsigned base ATTRIBUTE_UNUSED)
4ee9c684 408{
409 /* FIXME implement this. */
8c0963c4 410#ifdef ENABLE_CHECKING
411 internal_error ("unimplemented functionality");
412#endif
413 gcc_unreachable ();
4ee9c684 414}
415
48e1416a 416/* Output instructions as GIMPLE trees to increment the average histogram
417 counter. VALUE is the expression whose value is profiled. TAG is the
162719b3 418 tag of the section for counters, BASE is offset of the counter position. */
419
fc49fbc1 420void
421gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
162719b3 422{
75a70cf9 423 gimple stmt = value->hvalue.stmt;
424 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
a961cdc2 425 tree ref_ptr = tree_coverage_counter_addr (tag, base);
75a70cf9 426 gimple call;
427 tree val;
48e1416a 428
75a70cf9 429 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
0d734975 430 true, NULL_TREE,
75a70cf9 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);
6d3d8bf0 434 find_referenced_vars_in (call);
77fca8b5 435 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
162719b3 436}
437
48e1416a 438/* Output instructions as GIMPLE trees to increment the ior histogram
439 counter. VALUE is the expression whose value is profiled. TAG is the
162719b3 440 tag of the section for counters, BASE is offset of the counter position. */
441
fc49fbc1 442void
443gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
162719b3 444{
75a70cf9 445 gimple stmt = value->hvalue.stmt;
446 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
a961cdc2 447 tree ref_ptr = tree_coverage_counter_addr (tag, base);
75a70cf9 448 gimple call;
449 tree val;
48e1416a 450
75a70cf9 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);
6d3d8bf0 455 find_referenced_vars_in (call);
77fca8b5 456 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
162719b3 457}
458
85344eeb 459/* Profile all functions in the callgraph. */
4ee9c684 460
2a1990e9 461static unsigned int
d2971487 462tree_profiling (void)
463{
85344eeb 464 struct cgraph_node *node;
465
f517b36e 466 /* Don't profile functions produced at destruction time, particularly
b3a3ddec 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). */
85344eeb 470 if (cgraph_state == CGRAPH_STATE_FINISHED)
f517b36e 471 return 0;
f81207a7 472
1ad3e14c 473 init_node_map();
474
7c455d87 475 FOR_EACH_DEFINED_FUNCTION (node)
85344eeb 476 {
7c455d87 477 if (!gimple_has_body_p (node->symbol.decl))
85344eeb 478 continue;
479
480 /* Don't profile functions produced for builtin stuff. */
7d0d0ce1 481 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
482 || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
85344eeb 483 continue;
484
7d0d0ce1 485 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
486 current_function_decl = node->symbol.decl;
85344eeb 487
488 /* Re-set global shared temporary variable for edge-counters. */
489 gcov_type_tmp_var = NULL_TREE;
490
8c1fce46 491 /* Local pure-const may imply need to fixup the cfg. */
141de90e 492 if (execute_fixup_cfg () & TODO_cleanup_cfg)
493 cleanup_tree_cfg ();
85344eeb 494 branch_prob ();
495
496 if (! flag_branch_probabilities
497 && flag_profile_values)
fc49fbc1 498 gimple_gen_ic_func_profiler ();
85344eeb 499
500 if (flag_branch_probabilities
501 && flag_profile_values
502 && flag_value_profile_transformations)
fc49fbc1 503 gimple_value_profile_transformations ();
85344eeb 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. */
7c455d87 516 FOR_EACH_DEFINED_FUNCTION (node)
85344eeb 517 {
7c455d87 518 if (!gimple_has_body_p (node->symbol.decl)
7d0d0ce1 519 || !(!node->clone_of
520 || node->symbol.decl != node->clone_of->symbol.decl))
85344eeb 521 continue;
522
523 /* Don't profile functions produced for builtin stuff. */
7d0d0ce1 524 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
525 || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
85344eeb 526 continue;
527
7f74ac6b 528 cgraph_set_const_flag (node, false, false);
529 cgraph_set_pure_flag (node, false, false);
85344eeb 530 }
531
532 /* Update call statements and rebuild the cgraph. */
7c455d87 533 FOR_EACH_DEFINED_FUNCTION (node)
85344eeb 534 {
535 basic_block bb;
536
7c455d87 537 if (!gimple_has_body_p (node->symbol.decl)
7d0d0ce1 538 || !(!node->clone_of
539 || node->symbol.decl != node->clone_of->symbol.decl))
85344eeb 540 continue;
541
542 /* Don't profile functions produced for builtin stuff. */
7d0d0ce1 543 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
544 || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
85344eeb 545 continue;
546
7d0d0ce1 547 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
548 current_function_decl = node->symbol.decl;
85344eeb 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 }
fdc47e9a 569
1ad3e14c 570 del_node_map();
2a1990e9 571 return 0;
d2971487 572}
573
85344eeb 574/* When profile instrumentation, use or test coverage shall be performed. */
575
576static bool
577gate_tree_profile_ipa (void)
578{
579 return (!in_lto_p
580 && (flag_branch_probabilities || flag_test_coverage
581 || profile_arc_flag));
582}
583
584struct simple_ipa_opt_pass pass_ipa_tree_profile =
4ee9c684 585{
20099e35 586 {
85344eeb 587 SIMPLE_IPA_PASS,
855c9b82 588 "profile", /* name */
85344eeb 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 */
771e2890 599 0 /* todo_flags_finish */
20099e35 600 }
4ee9c684 601};
602
d7683f13 603#include "gt-tree-profile.h"