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