]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-profile.c
[6/6] Preprocessor forced macro location
[thirdparty/gcc.git] / gcc / tree-profile.c
CommitLineData
6de9cd9a 1/* Calculate branch probabilities, and basic block execution counts.
85ec4feb 2 Copyright (C) 1990-2018 Free Software Foundation, Inc.
6de9cd9a
DN
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
9dcd6f09 12Software Foundation; either version 3, or (at your option) any later
6de9cd9a
DN
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
9dcd6f09
NC
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
23
24/* Generate basic block profile instrumentation and auxiliary files.
1f1e8527 25 Tree-based version. See profile.c for overview. */
6de9cd9a
DN
26
27#include "config.h"
28#include "system.h"
29#include "coretypes.h"
4d0cdd0c 30#include "memmodel.h"
c7131fb2 31#include "backend.h"
957060b5 32#include "target.h"
c7131fb2
AM
33#include "tree.h"
34#include "gimple.h"
957060b5
AM
35#include "cfghooks.h"
36#include "tree-pass.h"
c7131fb2 37#include "ssa.h"
957060b5 38#include "cgraph.h"
6de9cd9a 39#include "coverage.h"
957060b5 40#include "diagnostic-core.h"
40e23961 41#include "fold-const.h"
d8a2d370
DN
42#include "varasm.h"
43#include "tree-nested.h"
45b0be94 44#include "gimplify.h"
5be5c238 45#include "gimple-iterator.h"
18f429e2 46#include "gimplify-me.h"
442b4905 47#include "tree-cfg.h"
442b4905 48#include "tree-into-ssa.h"
6de9cd9a 49#include "value-prof.h"
903d1e67 50#include "profile.h"
4484a35a 51#include "tree-cfgcleanup.h"
0a750165 52#include "params.h"
314e6352
ML
53#include "stringpool.h"
54#include "attribs.h"
a53d4f20 55#include "tree-pretty-print.h"
3edbcdbe
ML
56#include "langhooks.h"
57#include "stor-layout.h"
6de9cd9a 58
9885da8e
ZD
59static GTY(()) tree gcov_type_node;
60static GTY(()) tree tree_interval_profiler_fn;
61static GTY(()) tree tree_pow2_profiler_fn;
62static GTY(()) tree tree_one_value_profiler_fn;
6bad2617 63static GTY(()) tree tree_indirect_call_profiler_fn;
079a182e
JH
64static GTY(()) tree tree_average_profiler_fn;
65static GTY(()) tree tree_ior_profiler_fn;
7d29f8e3 66static GTY(()) tree tree_time_profiler_counter;
86ce5d2f 67
f3df9541 68
3edbcdbe
ML
69static GTY(()) tree ic_tuple_var;
70static GTY(()) tree ic_tuple_counters_field;
71static GTY(()) tree ic_tuple_callee_field;
6bad2617 72
f3df9541
AK
73/* Do initialization work for the edge profiler. */
74
6bad2617 75/* Add code:
2fa3d31b 76 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
86ce5d2f
ML
77 __thread void* __gcov_indirect_call_callee; // actual callee address
78 __thread int __gcov_function_counter; // time profiler function counter
6bad2617
TB
79*/
80static void
e0cb7e1e 81init_ic_make_global_vars (void)
6bad2617 82{
7d29f8e3 83 tree gcov_type_ptr;
6bad2617 84
3edbcdbe 85 gcov_type_ptr = build_pointer_type (get_gcov_type ());
b8698a0f 86
3edbcdbe 87 tree tuple_type = lang_hooks.types.make_type (RECORD_TYPE);
d984c8ef 88
3edbcdbe
ML
89 /* callee */
90 ic_tuple_callee_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
91 ptr_type_node);
c02ae3ae 92
3edbcdbe
ML
93 /* counters */
94 ic_tuple_counters_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
95 NULL_TREE, gcov_type_ptr);
96 DECL_CHAIN (ic_tuple_counters_field) = ic_tuple_callee_field;
97
98 finish_builtin_struct (tuple_type, "indirect_call_tuple",
99 ic_tuple_counters_field, NULL_TREE);
100
101 ic_tuple_var
c02ae3ae
JH
102 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
103 get_identifier (
104 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
3edbcdbe
ML
105 "__gcov_indirect_call_topn" :
106 "__gcov_indirect_call")),
107 tuple_type);
108 TREE_PUBLIC (ic_tuple_var) = 1;
109 DECL_ARTIFICIAL (ic_tuple_var) = 1;
110 DECL_INITIAL (ic_tuple_var) = NULL;
111 DECL_EXTERNAL (ic_tuple_var) = 1;
d984c8ef 112 if (targetm.have_tls)
3edbcdbe 113 set_decl_tls_model (ic_tuple_var, decl_default_tls_model (tuple_type));
6bad2617
TB
114}
115
9696c529
SB
116/* Create the type and function decls for the interface with gcov. */
117
e0cb7e1e 118void
7d29f8e3 119gimple_init_gcov_profiler (void)
f3df9541 120{
9885da8e
ZD
121 tree interval_profiler_fn_type;
122 tree pow2_profiler_fn_type;
123 tree one_value_profiler_fn_type;
124 tree gcov_type_ptr;
6bad2617 125 tree ic_profiler_fn_type;
079a182e 126 tree average_profiler_fn_type;
22063dbc 127 const char *profiler_fn_name;
a266236e 128 const char *fn_name;
9885da8e
ZD
129
130 if (!gcov_type_node)
131 {
a266236e
ML
132 const char *fn_suffix
133 = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : "";
134
9885da8e
ZD
135 gcov_type_node = get_gcov_type ();
136 gcov_type_ptr = build_pointer_type (gcov_type_node);
137
138 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
139 interval_profiler_fn_type
140 = build_function_type_list (void_type_node,
141 gcov_type_ptr, gcov_type_node,
142 integer_type_node,
143 unsigned_type_node, NULL_TREE);
a266236e
ML
144 fn_name = concat ("__gcov_interval_profiler", fn_suffix, NULL);
145 tree_interval_profiler_fn = build_fn_decl (fn_name,
146 interval_profiler_fn_type);
147 free (CONST_CAST (char *, fn_name));
4d3814a5
RG
148 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
149 DECL_ATTRIBUTES (tree_interval_profiler_fn)
150 = tree_cons (get_identifier ("leaf"), NULL,
151 DECL_ATTRIBUTES (tree_interval_profiler_fn));
9885da8e
ZD
152
153 /* void (*) (gcov_type *, gcov_type) */
154 pow2_profiler_fn_type
155 = build_function_type_list (void_type_node,
156 gcov_type_ptr, gcov_type_node,
157 NULL_TREE);
a266236e
ML
158 fn_name = concat ("__gcov_pow2_profiler", fn_suffix, NULL);
159 tree_pow2_profiler_fn = build_fn_decl (fn_name, pow2_profiler_fn_type);
160 free (CONST_CAST (char *, fn_name));
4d3814a5
RG
161 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
162 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
163 = tree_cons (get_identifier ("leaf"), NULL,
164 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
9885da8e
ZD
165
166 /* void (*) (gcov_type *, gcov_type) */
167 one_value_profiler_fn_type
168 = build_function_type_list (void_type_node,
169 gcov_type_ptr, gcov_type_node,
170 NULL_TREE);
a266236e
ML
171 fn_name = concat ("__gcov_one_value_profiler", fn_suffix, NULL);
172 tree_one_value_profiler_fn = build_fn_decl (fn_name,
173 one_value_profiler_fn_type);
174 free (CONST_CAST (char *, fn_name));
4d3814a5
RG
175 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
176 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
177 = tree_cons (get_identifier ("leaf"), NULL,
178 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
6bad2617 179
e0cb7e1e 180 init_ic_make_global_vars ();
b8698a0f 181
c02ae3ae
JH
182 /* void (*) (gcov_type, void *) */
183 ic_profiler_fn_type
184 = build_function_type_list (void_type_node,
185 gcov_type_node,
3edbcdbe 186 ptr_type_node,
c02ae3ae 187 NULL_TREE);
22063dbc
ML
188 profiler_fn_name = "__gcov_indirect_call_profiler_v2";
189 if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE))
190 profiler_fn_name = "__gcov_indirect_call_topn_profiler";
191
c02ae3ae 192 tree_indirect_call_profiler_fn
22063dbc 193 = build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
c02ae3ae 194
4d3814a5
RG
195 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
196 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
197 = tree_cons (get_identifier ("leaf"), NULL,
198 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
199
7d29f8e3
ML
200 tree_time_profiler_counter
201 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
202 get_identifier ("__gcov_time_profiler_counter"),
203 get_gcov_type ());
204 TREE_PUBLIC (tree_time_profiler_counter) = 1;
205 DECL_EXTERNAL (tree_time_profiler_counter) = 1;
206 TREE_STATIC (tree_time_profiler_counter) = 1;
207 DECL_ARTIFICIAL (tree_time_profiler_counter) = 1;
208 DECL_INITIAL (tree_time_profiler_counter) = NULL;
209
079a182e
JH
210 /* void (*) (gcov_type *, gcov_type) */
211 average_profiler_fn_type
212 = build_function_type_list (void_type_node,
213 gcov_type_ptr, gcov_type_node, NULL_TREE);
a266236e
ML
214 fn_name = concat ("__gcov_average_profiler", fn_suffix, NULL);
215 tree_average_profiler_fn = build_fn_decl (fn_name,
216 average_profiler_fn_type);
217 free (CONST_CAST (char *, fn_name));
4d3814a5
RG
218 TREE_NOTHROW (tree_average_profiler_fn) = 1;
219 DECL_ATTRIBUTES (tree_average_profiler_fn)
220 = tree_cons (get_identifier ("leaf"), NULL,
221 DECL_ATTRIBUTES (tree_average_profiler_fn));
a266236e
ML
222 fn_name = concat ("__gcov_ior_profiler", fn_suffix, NULL);
223 tree_ior_profiler_fn = build_fn_decl (fn_name, average_profiler_fn_type);
224 free (CONST_CAST (char *, fn_name));
4d3814a5
RG
225 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
226 DECL_ATTRIBUTES (tree_ior_profiler_fn)
227 = tree_cons (get_identifier ("leaf"), NULL,
228 DECL_ATTRIBUTES (tree_ior_profiler_fn));
229
0bc1b77f
JH
230 /* LTO streamer needs assembler names. Because we create these decls
231 late, we need to initialize them by hand. */
232 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
233 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
234 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
235 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
236 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
237 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
9885da8e 238 }
f3df9541
AK
239}
240
b8698a0f
L
241/* Output instructions as GIMPLE trees to increment the edge
242 execution count, and insert them on E. We rely on
726a989a 243 gsi_insert_on_edge to preserve the order. */
6de9cd9a 244
e0cb7e1e
SB
245void
246gimple_gen_edge_profiler (int edgeno, edge e)
6de9cd9a 247{
22063dbc 248 tree one;
9225443e 249
9225443e 250 one = build_int_cst (gcov_type_node, 1);
22063dbc
ML
251
252 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
253 {
254 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
255 tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
892a653c
ML
256 tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
257 ? BUILT_IN_ATOMIC_FETCH_ADD_8:
258 BUILT_IN_ATOMIC_FETCH_ADD_4);
259 gcall *stmt = gimple_build_call (f, 3, addr, one,
260 build_int_cst (integer_type_node,
261 MEMMODEL_RELAXED));
22063dbc
ML
262 gsi_insert_on_edge (e, stmt);
263 }
264 else
265 {
266 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
267 tree gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
268 NULL, "PROF_edge_counter");
269 gassign *stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
270 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
271 NULL, "PROF_edge_counter");
272 gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
273 gimple_assign_lhs (stmt1), one);
274 gassign *stmt3 = gimple_build_assign (unshare_expr (ref),
275 gimple_assign_lhs (stmt2));
276 gsi_insert_on_edge (e, stmt1);
277 gsi_insert_on_edge (e, stmt2);
278 gsi_insert_on_edge (e, stmt3);
279 }
6de9cd9a
DN
280}
281
726a989a 282/* Emits code to get VALUE to instrument at GSI, and returns the
9885da8e
ZD
283 variable containing the value. */
284
285static tree
726a989a 286prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
9885da8e 287{
8a76829c 288 tree val = value->hvalue.value;
ada39f0b 289 if (POINTER_TYPE_P (TREE_TYPE (val)))
0d82a1c8
RG
290 val = fold_convert (build_nonstandard_integer_type
291 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
726a989a
RB
292 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
293 true, NULL_TREE, true, GSI_SAME_STMT);
9885da8e
ZD
294}
295
b8698a0f
L
296/* Output instructions as GIMPLE trees to increment the interval histogram
297 counter. VALUE is the expression whose value is profiled. TAG is the
6de9cd9a
DN
298 tag of the section for counters, BASE is offset of the counter position. */
299
e0cb7e1e
SB
300void
301gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 302{
355fe088 303 gimple *stmt = value->hvalue.stmt;
726a989a 304 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
9885da8e 305 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
538dd0b7 306 gcall *call;
726a989a
RB
307 tree val;
308 tree start = build_int_cst_type (integer_type_node,
309 value->hdata.intvl.int_start);
310 tree steps = build_int_cst_type (unsigned_type_node,
311 value->hdata.intvl.steps);
b8698a0f 312
726a989a 313 ref_ptr = force_gimple_operand_gsi (&gsi,
aa00059c 314 build_addr (ref),
726a989a
RB
315 true, NULL_TREE, true, GSI_SAME_STMT);
316 val = prepare_instrumented_value (&gsi, value);
317 call = gimple_build_call (tree_interval_profiler_fn, 4,
318 ref_ptr, val, start, steps);
71ba42fa 319 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
6de9cd9a
DN
320}
321
b8698a0f
L
322/* Output instructions as GIMPLE trees to increment the power of two histogram
323 counter. VALUE is the expression whose value is profiled. TAG is the tag
6de9cd9a
DN
324 of the section for counters, BASE is offset of the counter position. */
325
e0cb7e1e
SB
326void
327gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 328{
355fe088 329 gimple *stmt = value->hvalue.stmt;
726a989a 330 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 331 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 332 gcall *call;
726a989a 333 tree val;
b8698a0f 334
726a989a
RB
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_pow2_profiler_fn, 2, ref_ptr, val);
71ba42fa 339 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
6de9cd9a
DN
340}
341
342/* Output instructions as GIMPLE trees for code to find the most common value.
343 VALUE is the expression whose value is profiled. TAG is the tag of the
344 section for counters, BASE is offset of the counter position. */
345
e0cb7e1e
SB
346void
347gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 348{
355fe088 349 gimple *stmt = value->hvalue.stmt;
726a989a 350 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 351 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 352 gcall *call;
726a989a 353 tree val;
b8698a0f 354
726a989a
RB
355 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
356 true, NULL_TREE, true, GSI_SAME_STMT);
357 val = prepare_instrumented_value (&gsi, value);
358 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
71ba42fa 359 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
6de9cd9a
DN
360}
361
6bad2617
TB
362
363/* Output instructions as GIMPLE trees for code to find the most
b8698a0f 364 common called function in indirect call.
88512ba0 365 VALUE is the call expression whose indirect callee is profiled.
6bad2617
TB
366 TAG is the tag of the section for counters, BASE is offset of the
367 counter position. */
368
e0cb7e1e
SB
369void
370gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
6bad2617 371{
726a989a 372 tree tmp1;
538dd0b7 373 gassign *stmt1, *stmt2, *stmt3;
355fe088 374 gimple *stmt = value->hvalue.stmt;
726a989a 375 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 376 tree ref_ptr = tree_coverage_counter_addr (tag, base);
6bad2617 377
0a750165
RX
378 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
379 tag == GCOV_COUNTER_V_INDIR) ||
380 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
381 tag == GCOV_COUNTER_ICALL_TOPNV))
382 return;
383
726a989a
RB
384 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
385 true, NULL_TREE, true, GSI_SAME_STMT);
6bad2617
TB
386
387 /* Insert code:
b8698a0f 388
3edbcdbe 389 stmt1: __gcov_indirect_call.counters = get_relevant_counter_ptr ();
9696c529 390 stmt2: tmp1 = (void *) (indirect call argument value)
3edbcdbe 391 stmt3: __gcov_indirect_call.callee = tmp1;
4f751c54
ML
392
393 Example:
394 f_1 = foo;
3edbcdbe 395 __gcov_indirect_call.counters = &__gcov4.main[0];
4f751c54
ML
396 PROF_9 = f_1;
397 __gcov_indirect_call_callee = PROF_9;
398 _4 = f_1 ();
6bad2617
TB
399 */
400
3edbcdbe
ML
401 tree gcov_type_ptr = build_pointer_type (get_gcov_type ());
402
403 tree counter_ref = build3 (COMPONENT_REF, gcov_type_ptr,
404 ic_tuple_var, ic_tuple_counters_field, NULL_TREE);
405
406 stmt1 = gimple_build_assign (counter_ref, ref_ptr);
407 tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF");
726a989a 408 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
3edbcdbe
ML
409 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
410 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
411 stmt3 = gimple_build_assign (callee_ref, tmp1);
6bad2617 412
726a989a
RB
413 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
414 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
415 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
6bad2617
TB
416}
417
418
419/* Output instructions as GIMPLE trees for code to find the most
420 common called function in indirect call. Insert instructions at the
88512ba0 421 beginning of every possible called function.
6bad2617
TB
422 */
423
e0cb7e1e
SB
424void
425gimple_gen_ic_func_profiler (void)
6bad2617 426{
d52f5295 427 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
538dd0b7 428 gcall *stmt1;
2fa3d31b 429 tree tree_uid, cur_func, void0;
6bad2617 430
d52f5295 431 if (c_node->only_called_directly_p ())
7e8b322a 432 return;
b8698a0f 433
7d29f8e3 434 gimple_init_gcov_profiler ();
b8698a0f 435
4f751c54
ML
436 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
437 basic_block cond_bb = split_edge (single_succ_edge (entry));
438 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
439
c9c15e27
ML
440 /* We need to do an extra split in order to not create an input
441 for a possible PHI node. */
442 split_edge (single_succ_edge (update_bb));
443
4f751c54
ML
444 edge true_edge = single_succ_edge (cond_bb);
445 true_edge->flags = EDGE_TRUE_VALUE;
446
357067f2 447 profile_probability probability;
4f751c54 448 if (DECL_VIRTUAL_P (current_function_decl))
357067f2 449 probability = profile_probability::very_likely ();
4f751c54 450 else
357067f2 451 probability = profile_probability::unlikely ();
4f751c54
ML
452
453 true_edge->probability = probability;
454 edge e = make_edge (cond_bb, single_succ_edge (update_bb)->dest,
455 EDGE_FALSE_VALUE);
357067f2 456 e->probability = true_edge->probability.invert ();
4f751c54 457
9696c529
SB
458 /* Insert code:
459
4f751c54
ML
460 if (__gcov_indirect_call_callee != NULL)
461 __gcov_indirect_call_profiler_v2 (profile_id, &current_function_decl);
462
463 The function __gcov_indirect_call_profiler_v2 is responsible for
464 resetting __gcov_indirect_call_callee to NULL. */
465
466 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
3edbcdbe
ML
467 void0 = build_int_cst (ptr_type_node, 0);
468
469 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
470 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
4f751c54 471
3edbcdbe 472 tree ref = force_gimple_operand_gsi (&gsi, callee_ref, true, NULL_TREE,
4f751c54
ML
473 true, GSI_SAME_STMT);
474
475 gcond *cond = gimple_build_cond (NE_EXPR, ref,
476 void0, NULL, NULL);
477 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
478
479 gsi = gsi_after_labels (update_bb);
4d3814a5
RG
480
481 cur_func = force_gimple_operand_gsi (&gsi,
aa00059c 482 build_addr (current_function_decl),
4d3814a5
RG
483 true, NULL_TREE,
484 true, GSI_SAME_STMT);
2fa3d31b 485 tree_uid = build_int_cst
c02ae3ae
JH
486 (gcov_type_node,
487 cgraph_node::get (current_function_decl)->profile_id);
488 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
489 tree_uid, cur_func);
4d3814a5 490 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
6bad2617
TB
491}
492
86ce5d2f
ML
493/* Output instructions as GIMPLE tree at the beginning for each function.
494 TAG is the tag of the section for counters, BASE is offset of the
495 counter position and GSI is the iterator we place the counter. */
496
497void
7d29f8e3 498gimple_gen_time_profiler (unsigned tag, unsigned base)
86ce5d2f 499{
7d29f8e3 500 tree type = get_gcov_type ();
248cce34
ML
501 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
502 basic_block cond_bb = split_edge (single_succ_edge (entry));
7d29f8e3
ML
503 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
504
c9c15e27
ML
505 /* We need to do an extra split in order to not create an input
506 for a possible PHI node. */
507 split_edge (single_succ_edge (update_bb));
508
7d29f8e3
ML
509 edge true_edge = single_succ_edge (cond_bb);
510 true_edge->flags = EDGE_TRUE_VALUE;
357067f2 511 true_edge->probability = profile_probability::unlikely ();
7d29f8e3
ML
512 edge e
513 = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
357067f2 514 e->probability = true_edge->probability.invert ();
7d29f8e3
ML
515
516 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
517 tree original_ref = tree_coverage_counter_ref (tag, base);
518 tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE,
519 true, GSI_SAME_STMT);
520 tree one = build_int_cst (type, 1);
86ce5d2f 521
7d29f8e3
ML
522 /* Emit: if (counters[0] != 0). */
523 gcond *cond = gimple_build_cond (EQ_EXPR, ref, build_int_cst (type, 0),
524 NULL, NULL);
525 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
526
527 gsi = gsi_start_bb (update_bb);
528
529 /* Emit: counters[0] = ++__gcov_time_profiler_counter. */
530 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
531 {
5bcb571c
ML
532 tree ptr = make_temp_ssa_name (build_pointer_type (type), NULL,
533 "time_profiler_counter_ptr");
534 tree addr = build1 (ADDR_EXPR, TREE_TYPE (ptr),
7d29f8e3
ML
535 tree_time_profiler_counter);
536 gassign *assign = gimple_build_assign (ptr, NOP_EXPR, addr);
537 gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
538 tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
539 ? BUILT_IN_ATOMIC_ADD_FETCH_8:
540 BUILT_IN_ATOMIC_ADD_FETCH_4);
541 gcall *stmt = gimple_build_call (f, 3, ptr, one,
542 build_int_cst (integer_type_node,
543 MEMMODEL_RELAXED));
544 tree result_type = TREE_TYPE (TREE_TYPE (f));
545 tree tmp = make_temp_ssa_name (result_type, NULL, "time_profile");
546 gimple_set_lhs (stmt, tmp);
547 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
548 tmp = make_temp_ssa_name (type, NULL, "time_profile");
549 assign = gimple_build_assign (tmp, NOP_EXPR,
550 gimple_call_lhs (stmt));
551 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
552 assign = gimple_build_assign (original_ref, tmp);
553 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
554 }
555 else
556 {
557 tree tmp = make_temp_ssa_name (type, NULL, "time_profile");
558 gassign *assign = gimple_build_assign (tmp, tree_time_profiler_counter);
559 gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
560
561 tmp = make_temp_ssa_name (type, NULL, "time_profile");
562 assign = gimple_build_assign (tmp, PLUS_EXPR, gimple_assign_lhs (assign),
563 one);
564 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
565 assign = gimple_build_assign (original_ref, tmp);
566 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
567 assign = gimple_build_assign (tree_time_profiler_counter, tmp);
568 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
569 }
86ce5d2f
ML
570}
571
b8698a0f
L
572/* Output instructions as GIMPLE trees to increment the average histogram
573 counter. VALUE is the expression whose value is profiled. TAG is the
079a182e
JH
574 tag of the section for counters, BASE is offset of the counter position. */
575
e0cb7e1e
SB
576void
577gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
079a182e 578{
355fe088 579 gimple *stmt = value->hvalue.stmt;
726a989a 580 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 581 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 582 gcall *call;
726a989a 583 tree val;
b8698a0f 584
726a989a 585 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
c6540bde 586 true, NULL_TREE,
726a989a
RB
587 true, GSI_SAME_STMT);
588 val = prepare_instrumented_value (&gsi, value);
589 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
71ba42fa 590 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
079a182e
JH
591}
592
b8698a0f
L
593/* Output instructions as GIMPLE trees to increment the ior histogram
594 counter. VALUE is the expression whose value is profiled. TAG is the
079a182e
JH
595 tag of the section for counters, BASE is offset of the counter position. */
596
e0cb7e1e
SB
597void
598gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
079a182e 599{
355fe088 600 gimple *stmt = value->hvalue.stmt;
726a989a 601 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 602 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 603 gcall *call;
726a989a 604 tree val;
b8698a0f 605
726a989a
RB
606 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
607 true, NULL_TREE, true, GSI_SAME_STMT);
608 val = prepare_instrumented_value (&gsi, value);
609 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
71ba42fa 610 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
079a182e
JH
611}
612
7fe76f6a
ML
613#ifndef HAVE_sync_compare_and_swapsi
614#define HAVE_sync_compare_and_swapsi 0
615#endif
616#ifndef HAVE_atomic_compare_and_swapsi
617#define HAVE_atomic_compare_and_swapsi 0
618#endif
619
620#ifndef HAVE_sync_compare_and_swapdi
621#define HAVE_sync_compare_and_swapdi 0
622#endif
623#ifndef HAVE_atomic_compare_and_swapdi
624#define HAVE_atomic_compare_and_swapdi 0
625#endif
626
4d3814a5 627/* Profile all functions in the callgraph. */
6de9cd9a 628
c2924966 629static unsigned int
1f1e8527
DJ
630tree_profiling (void)
631{
4d3814a5
RG
632 struct cgraph_node *node;
633
7fe76f6a 634 /* Verify whether we can utilize atomic update operations. */
4d209853
ML
635 bool can_support_atomic = false;
636 unsigned HOST_WIDE_INT gcov_type_size
637 = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
638 if (gcov_type_size == 4)
639 can_support_atomic
640 = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
641 else if (gcov_type_size == 8)
642 can_support_atomic
643 = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
644
645 if (flag_profile_update == PROFILE_UPDATE_ATOMIC
646 && !can_support_atomic)
7fe76f6a 647 {
4d209853
ML
648 warning (0, "target does not support atomic profile update, "
649 "single mode is selected");
650 flag_profile_update = PROFILE_UPDATE_SINGLE;
7fe76f6a 651 }
4d209853
ML
652 else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
653 flag_profile_update = can_support_atomic
654 ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
7fe76f6a 655
9696c529
SB
656 /* This is a small-ipa pass that gets called only once, from
657 cgraphunit.c:ipa_passes(). */
3dafb85c 658 gcc_assert (symtab->state == IPA_SSA);
9225443e 659
2fa3d31b 660 init_node_map (true);
903d1e67 661
65c70e6b 662 FOR_EACH_DEFINED_FUNCTION (node)
4d3814a5 663 {
67348ccc 664 if (!gimple_has_body_p (node->decl))
4d3814a5
RG
665 continue;
666
667 /* Don't profile functions produced for builtin stuff. */
67348ccc 668 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
4d3814a5
RG
669 continue;
670
1225d6b1
ML
671 if (lookup_attribute ("no_profile_instrument_function",
672 DECL_ATTRIBUTES (node->decl)))
673 continue;
07db0f9b
JH
674 /* Do not instrument extern inline functions when testing coverage.
675 While this is not perfectly consistent (early inlined extern inlines
676 will get acocunted), testsuite expects that. */
677 if (DECL_EXTERNAL (node->decl)
678 && flag_test_coverage)
679 continue;
680
67348ccc 681 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4d3814a5 682
a53d4f20
ML
683 if (dump_file)
684 dump_function_header (dump_file, cfun->decl, dump_flags);
685
71fb4f92 686 /* Local pure-const may imply need to fixup the cfg. */
49bdc0a6
RG
687 if (execute_fixup_cfg () & TODO_cleanup_cfg)
688 cleanup_tree_cfg ();
9696c529 689
4d3814a5
RG
690 branch_prob ();
691
692 if (! flag_branch_probabilities
693 && flag_profile_values)
e0cb7e1e 694 gimple_gen_ic_func_profiler ();
4d3814a5
RG
695
696 if (flag_branch_probabilities
697 && flag_profile_values
698 && flag_value_profile_transformations)
e0cb7e1e 699 gimple_value_profile_transformations ();
4d3814a5
RG
700
701 /* The above could hose dominator info. Currently there is
702 none coming in, this is a safety valve. It should be
703 easy to adjust it, if and when there is some. */
704 free_dominance_info (CDI_DOMINATORS);
705 free_dominance_info (CDI_POST_DOMINATORS);
4d3814a5
RG
706 pop_cfun ();
707 }
708
709 /* Drop pure/const flags from instrumented functions. */
86b7136a
JH
710 if (profile_arc_flag || flag_test_coverage)
711 FOR_EACH_DEFINED_FUNCTION (node)
712 {
713 if (!gimple_has_body_p (node->decl)
714 || !(!node->clone_of
715 || node->decl != node->clone_of->decl))
716 continue;
717
718 /* Don't profile functions produced for builtin stuff. */
719 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
720 continue;
721
722 node->set_const_flag (false, false);
723 node->set_pure_flag (false, false);
724 }
4d3814a5
RG
725
726 /* Update call statements and rebuild the cgraph. */
65c70e6b 727 FOR_EACH_DEFINED_FUNCTION (node)
4d3814a5
RG
728 {
729 basic_block bb;
730
67348ccc 731 if (!gimple_has_body_p (node->decl)
960bfb69 732 || !(!node->clone_of
67348ccc 733 || node->decl != node->clone_of->decl))
4d3814a5
RG
734 continue;
735
736 /* Don't profile functions produced for builtin stuff. */
67348ccc 737 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
4d3814a5
RG
738 continue;
739
67348ccc 740 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4d3814a5 741
11cd3bed 742 FOR_EACH_BB_FN (bb, cfun)
4d3814a5
RG
743 {
744 gimple_stmt_iterator gsi;
745 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
746 {
355fe088 747 gimple *stmt = gsi_stmt (gsi);
4d3814a5
RG
748 if (is_gimple_call (stmt))
749 update_stmt (stmt);
750 }
751 }
752
a64bbb3f
JH
753 /* re-merge split blocks. */
754 cleanup_tree_cfg ();
4d3814a5
RG
755 update_ssa (TODO_update_ssa);
756
3dafb85c 757 cgraph_edge::rebuild_edges ();
4d3814a5 758
4d3814a5
RG
759 pop_cfun ();
760 }
f7b4a383 761
eb4b92c1
TJ
762 handle_missing_profiles ();
763
c3284718 764 del_node_map ();
c2924966 765 return 0;
1f1e8527
DJ
766}
767
27a4cd48
DM
768namespace {
769
770const pass_data pass_data_ipa_tree_profile =
6de9cd9a 771{
27a4cd48
DM
772 SIMPLE_IPA_PASS, /* type */
773 "profile", /* name */
774 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
775 TV_IPA_PROFILE, /* tv_id */
776 0, /* properties_required */
777 0, /* properties_provided */
778 0, /* properties_destroyed */
779 0, /* todo_flags_start */
86b7136a 780 TODO_dump_symtab, /* todo_flags_finish */
6de9cd9a
DN
781};
782
27a4cd48
DM
783class pass_ipa_tree_profile : public simple_ipa_opt_pass
784{
785public:
c3284718
RS
786 pass_ipa_tree_profile (gcc::context *ctxt)
787 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
27a4cd48
DM
788 {}
789
790 /* opt_pass methods: */
1a3d085c 791 virtual bool gate (function *);
be55bfe6 792 virtual unsigned int execute (function *) { return tree_profiling (); }
27a4cd48
DM
793
794}; // class pass_ipa_tree_profile
795
1a3d085c
TS
796bool
797pass_ipa_tree_profile::gate (function *)
798{
be3c16c4
DC
799 /* When profile instrumentation, use or test coverage shall be performed.
800 But for AutoFDO, this there is no instrumentation, thus this pass is
801 diabled. */
802 return (!in_lto_p && !flag_auto_profile
1a3d085c
TS
803 && (flag_branch_probabilities || flag_test_coverage
804 || profile_arc_flag));
805}
806
27a4cd48
DM
807} // anon namespace
808
809simple_ipa_opt_pass *
810make_pass_ipa_tree_profile (gcc::context *ctxt)
811{
812 return new pass_ipa_tree_profile (ctxt);
813}
814
9885da8e 815#include "gt-tree-profile.h"