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