expr.c (emit_single_push_insn): If padding is needed downward...
[gcc.git] / gcc / profile.c
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
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 2, 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 COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 02111-1307, USA. */
24
25 /* Generate basic block profile instrumentation and auxiliary files.
26 Profile generation is optimized, so that not all arcs in the basic
27 block graph need instrumenting. First, the BB graph is closed with
28 one entry (function start), and one exit (function exit). Any
29 ABNORMAL_EDGE cannot be instrumented (because there is no control
30 path to place the code). We close the graph by inserting fake
31 EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
32 edges that do not go to the exit_block. We ignore such abnormal
33 edges. Naturally these fake edges are never directly traversed,
34 and so *cannot* be directly instrumented. Some other graph
35 massaging is done. To optimize the instrumentation we generate the
36 BB minimal span tree, only edges that are not on the span tree
37 (plus the entry point) need instrumenting. From that information
38 all other edge counts can be deduced. By construction all fake
39 edges must be on the spanning tree. We also attempt to place
40 EDGE_CRITICAL edges on the spanning tree.
41
42 The auxiliary file generated is <dumpbase>.bbg. The format is
43 described in full in gcov-io.h. */
44
45 /* ??? Register allocation should use basic block execution counts to
46 give preference to the most commonly executed blocks. */
47
48 /* ??? Should calculate branch probabilities before instrumenting code, since
49 then we can use arc counts to help decide which arcs to instrument. */
50
51 #include "config.h"
52 #include "system.h"
53 #include "coretypes.h"
54 #include "tm.h"
55 #include "rtl.h"
56 #include "flags.h"
57 #include "output.h"
58 #include "regs.h"
59 #include "expr.h"
60 #include "function.h"
61 #include "toplev.h"
62 #include "coverage.h"
63 #include "value-prof.h"
64 #include "tree.h"
65
66 /* Additional information about the edges we need. */
67 struct edge_info {
68 unsigned int count_valid : 1;
69
70 /* Is on the spanning tree. */
71 unsigned int on_tree : 1;
72
73 /* Pretend this edge does not exist (it is abnormal and we've
74 inserted a fake to compensate). */
75 unsigned int ignore : 1;
76 };
77
78 struct bb_info {
79 unsigned int count_valid : 1;
80
81 /* Number of successor and predecessor edges. */
82 gcov_type succ_count;
83 gcov_type pred_count;
84 };
85
86 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
87 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
88
89 /* Counter summary from the last set of coverage counts read. */
90
91 const struct gcov_ctr_summary *profile_info;
92
93 /* Collect statistics on the performance of this pass for the entire source
94 file. */
95
96 static int total_num_blocks;
97 static int total_num_edges;
98 static int total_num_edges_ignored;
99 static int total_num_edges_instrumented;
100 static int total_num_blocks_created;
101 static int total_num_passes;
102 static int total_num_times_called;
103 static int total_hist_br_prob[20];
104 static int total_num_never_executed;
105 static int total_num_branches;
106
107 /* Forward declarations. */
108 static void find_spanning_tree PARAMS ((struct edge_list *));
109 static rtx gen_edge_profiler PARAMS ((int));
110 static rtx gen_interval_profiler (struct histogram_value *, unsigned, unsigned);
111 static rtx gen_pow2_profiler (struct histogram_value *, unsigned, unsigned);
112 static rtx gen_one_value_profiler (struct histogram_value *, unsigned, unsigned);
113 static rtx gen_const_delta_profiler (struct histogram_value *, unsigned, unsigned);
114 static unsigned instrument_edges PARAMS ((struct edge_list *));
115 static void instrument_values (unsigned, struct histogram_value *);
116 static void compute_branch_probabilities PARAMS ((void));
117 static gcov_type * get_exec_counts PARAMS ((void));
118 static basic_block find_group PARAMS ((basic_block));
119 static void union_groups PARAMS ((basic_block, basic_block));
120
121 \f
122 /* Add edge instrumentation code to the entire insn chain.
123
124 F is the first insn of the chain.
125 NUM_BLOCKS is the number of basic blocks found in F. */
126
127 static unsigned
128 instrument_edges (el)
129 struct edge_list *el;
130 {
131 unsigned num_instr_edges = 0;
132 int num_edges = NUM_EDGES (el);
133 basic_block bb;
134
135 remove_fake_edges ();
136
137 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
138 {
139 edge e;
140
141 for (e = bb->succ; e; e = e->succ_next)
142 {
143 struct edge_info *inf = EDGE_INFO (e);
144
145 if (!inf->ignore && !inf->on_tree)
146 {
147 rtx edge_profile;
148
149 if (e->flags & EDGE_ABNORMAL)
150 abort ();
151 if (rtl_dump_file)
152 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
153 e->src->index, e->dest->index,
154 EDGE_CRITICAL_P (e) ? " (and split)" : "");
155 edge_profile = gen_edge_profiler (num_instr_edges++);
156 insert_insn_on_edge (edge_profile, e);
157 rebuild_jump_labels (e->insns);
158 }
159 }
160 }
161
162 total_num_blocks_created += num_edges;
163 if (rtl_dump_file)
164 fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
165 return num_instr_edges;
166 }
167
168 /* Add code to measure histograms list of VALUES of length N_VALUES. */
169 static void
170 instrument_values (unsigned n_values, struct histogram_value *values)
171 {
172 rtx sequence;
173 unsigned i, t;
174 edge e;
175
176 /* Emit code to generate the histograms before the insns. */
177
178 for (i = 0; i < n_values; i++)
179 {
180 e = split_block (BLOCK_FOR_INSN (values[i].insn),
181 PREV_INSN (values[i].insn));
182 switch (values[i].type)
183 {
184 case HIST_TYPE_INTERVAL:
185 t = GCOV_COUNTER_V_INTERVAL;
186 break;
187
188 case HIST_TYPE_POW2:
189 t = GCOV_COUNTER_V_POW2;
190 break;
191
192 case HIST_TYPE_SINGLE_VALUE:
193 t = GCOV_COUNTER_V_SINGLE;
194 break;
195
196 case HIST_TYPE_CONST_DELTA:
197 t = GCOV_COUNTER_V_DELTA;
198 break;
199
200 default:
201 abort ();
202 }
203 if (!coverage_counter_alloc (t, values[i].n_counters))
204 continue;
205
206 switch (values[i].type)
207 {
208 case HIST_TYPE_INTERVAL:
209 sequence = gen_interval_profiler (values + i, t, 0);
210 break;
211
212 case HIST_TYPE_POW2:
213 sequence = gen_pow2_profiler (values + i, t, 0);
214 break;
215
216 case HIST_TYPE_SINGLE_VALUE:
217 sequence = gen_one_value_profiler (values + i, t, 0);
218 break;
219
220 case HIST_TYPE_CONST_DELTA:
221 sequence = gen_const_delta_profiler (values + i, t, 0);
222 break;
223
224 default:
225 abort ();
226 }
227
228 safe_insert_insn_on_edge (sequence, e);
229 }
230 }
231 \f
232
233 /* Computes hybrid profile for all matching entries in da_file. */
234
235 static gcov_type *
236 get_exec_counts ()
237 {
238 unsigned num_edges = 0;
239 basic_block bb;
240 gcov_type *counts;
241
242 /* Count the edges to be (possibly) instrumented. */
243 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
244 {
245 edge e;
246 for (e = bb->succ; e; e = e->succ_next)
247 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
248 num_edges++;
249 }
250
251 counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, &profile_info);
252 if (!counts)
253 return NULL;
254
255 if (rtl_dump_file && profile_info)
256 fprintf(rtl_dump_file, "Merged %u profiles with maximal count %u.\n",
257 profile_info->runs, (unsigned) profile_info->sum_max);
258
259 return counts;
260 }
261 \f
262
263 /* Compute the branch probabilities for the various branches.
264 Annotate them accordingly. */
265
266 static void
267 compute_branch_probabilities ()
268 {
269 basic_block bb;
270 int i;
271 int num_edges = 0;
272 int changes;
273 int passes;
274 int hist_br_prob[20];
275 int num_never_executed;
276 int num_branches;
277 gcov_type *exec_counts = get_exec_counts ();
278 int exec_counts_pos = 0;
279
280 /* Attach extra info block to each bb. */
281
282 alloc_aux_for_blocks (sizeof (struct bb_info));
283 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
284 {
285 edge e;
286
287 for (e = bb->succ; e; e = e->succ_next)
288 if (!EDGE_INFO (e)->ignore)
289 BB_INFO (bb)->succ_count++;
290 for (e = bb->pred; e; e = e->pred_next)
291 if (!EDGE_INFO (e)->ignore)
292 BB_INFO (bb)->pred_count++;
293 }
294
295 /* Avoid predicting entry on exit nodes. */
296 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
297 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
298
299 /* For each edge not on the spanning tree, set its execution count from
300 the .da file. */
301
302 /* The first count in the .da file is the number of times that the function
303 was entered. This is the exec_count for block zero. */
304
305 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
306 {
307 edge e;
308 for (e = bb->succ; e; e = e->succ_next)
309 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
310 {
311 num_edges++;
312 if (exec_counts)
313 {
314 e->count = exec_counts[exec_counts_pos++];
315 }
316 else
317 e->count = 0;
318
319 EDGE_INFO (e)->count_valid = 1;
320 BB_INFO (bb)->succ_count--;
321 BB_INFO (e->dest)->pred_count--;
322 if (rtl_dump_file)
323 {
324 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
325 bb->index, e->dest->index);
326 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
327 (HOST_WIDEST_INT) e->count);
328 }
329 }
330 }
331
332 if (rtl_dump_file)
333 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
334
335 /* For every block in the file,
336 - if every exit/entrance edge has a known count, then set the block count
337 - if the block count is known, and every exit/entrance edge but one has
338 a known execution count, then set the count of the remaining edge
339
340 As edge counts are set, decrement the succ/pred count, but don't delete
341 the edge, that way we can easily tell when all edges are known, or only
342 one edge is unknown. */
343
344 /* The order that the basic blocks are iterated through is important.
345 Since the code that finds spanning trees starts with block 0, low numbered
346 edges are put on the spanning tree in preference to high numbered edges.
347 Hence, most instrumented edges are at the end. Graph solving works much
348 faster if we propagate numbers from the end to the start.
349
350 This takes an average of slightly more than 3 passes. */
351
352 changes = 1;
353 passes = 0;
354 while (changes)
355 {
356 passes++;
357 changes = 0;
358 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
359 {
360 struct bb_info *bi = BB_INFO (bb);
361 if (! bi->count_valid)
362 {
363 if (bi->succ_count == 0)
364 {
365 edge e;
366 gcov_type total = 0;
367
368 for (e = bb->succ; e; e = e->succ_next)
369 total += e->count;
370 bb->count = total;
371 bi->count_valid = 1;
372 changes = 1;
373 }
374 else if (bi->pred_count == 0)
375 {
376 edge e;
377 gcov_type total = 0;
378
379 for (e = bb->pred; e; e = e->pred_next)
380 total += e->count;
381 bb->count = total;
382 bi->count_valid = 1;
383 changes = 1;
384 }
385 }
386 if (bi->count_valid)
387 {
388 if (bi->succ_count == 1)
389 {
390 edge e;
391 gcov_type total = 0;
392
393 /* One of the counts will be invalid, but it is zero,
394 so adding it in also doesn't hurt. */
395 for (e = bb->succ; e; e = e->succ_next)
396 total += e->count;
397
398 /* Seedgeh for the invalid edge, and set its count. */
399 for (e = bb->succ; e; e = e->succ_next)
400 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
401 break;
402
403 /* Calculate count for remaining edge by conservation. */
404 total = bb->count - total;
405
406 if (! e)
407 abort ();
408 EDGE_INFO (e)->count_valid = 1;
409 e->count = total;
410 bi->succ_count--;
411
412 BB_INFO (e->dest)->pred_count--;
413 changes = 1;
414 }
415 if (bi->pred_count == 1)
416 {
417 edge e;
418 gcov_type total = 0;
419
420 /* One of the counts will be invalid, but it is zero,
421 so adding it in also doesn't hurt. */
422 for (e = bb->pred; e; e = e->pred_next)
423 total += e->count;
424
425 /* Search for the invalid edge, and set its count. */
426 for (e = bb->pred; e; e = e->pred_next)
427 if (!EDGE_INFO (e)->count_valid && !EDGE_INFO (e)->ignore)
428 break;
429
430 /* Calculate count for remaining edge by conservation. */
431 total = bb->count - total + e->count;
432
433 if (! e)
434 abort ();
435 EDGE_INFO (e)->count_valid = 1;
436 e->count = total;
437 bi->pred_count--;
438
439 BB_INFO (e->src)->succ_count--;
440 changes = 1;
441 }
442 }
443 }
444 }
445 if (rtl_dump_file)
446 dump_flow_info (rtl_dump_file);
447
448 total_num_passes += passes;
449 if (rtl_dump_file)
450 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
451
452 /* If the graph has been correctly solved, every block will have a
453 succ and pred count of zero. */
454 FOR_EACH_BB (bb)
455 {
456 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
457 abort ();
458 }
459
460 /* For every edge, calculate its branch probability and add a reg_note
461 to the branch insn to indicate this. */
462
463 for (i = 0; i < 20; i++)
464 hist_br_prob[i] = 0;
465 num_never_executed = 0;
466 num_branches = 0;
467
468 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
469 {
470 edge e;
471 rtx note;
472
473 if (bb->count < 0)
474 {
475 error ("corrupted profile info: number of iterations for basic block %d thought to be %i",
476 bb->index, (int)bb->count);
477 bb->count = 0;
478 }
479 for (e = bb->succ; e; e = e->succ_next)
480 {
481 /* Function may return twice in the cased the called fucntion is
482 setjmp or calls fork, but we can't represent this by extra
483 edge from the entry, since extra edge from the exit is
484 already present. We get negative frequency from the entry
485 point. */
486 if ((e->count < 0
487 && e->dest == EXIT_BLOCK_PTR)
488 || (e->count > bb->count
489 && e->dest != EXIT_BLOCK_PTR))
490 {
491 rtx insn = bb->end;
492
493 while (GET_CODE (insn) != CALL_INSN
494 && insn != bb->head
495 && keep_with_call_p (insn))
496 insn = PREV_INSN (insn);
497 if (GET_CODE (insn) == CALL_INSN)
498 e->count = e->count < 0 ? 0 : bb->count;
499 }
500 if (e->count < 0 || e->count > bb->count)
501 {
502 error ("corrupted profile info: number of executions for edge %d-%d thought to be %i",
503 e->src->index, e->dest->index,
504 (int)e->count);
505 e->count = bb->count / 2;
506 }
507 }
508 if (bb->count)
509 {
510 for (e = bb->succ; e; e = e->succ_next)
511 e->probability = (e->count * REG_BR_PROB_BASE + bb->count / 2) / bb->count;
512 if (bb->index >= 0
513 && any_condjump_p (bb->end)
514 && bb->succ->succ_next)
515 {
516 int prob;
517 edge e;
518 int index;
519
520 /* Find the branch edge. It is possible that we do have fake
521 edges here. */
522 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
523 e = e->succ_next)
524 continue; /* Loop body has been intentionally left blank. */
525
526 prob = e->probability;
527 index = prob * 20 / REG_BR_PROB_BASE;
528
529 if (index == 20)
530 index = 19;
531 hist_br_prob[index]++;
532
533 note = find_reg_note (bb->end, REG_BR_PROB, 0);
534 /* There may be already note put by some other pass, such
535 as builtin_expect expander. */
536 if (note)
537 XEXP (note, 0) = GEN_INT (prob);
538 else
539 REG_NOTES (bb->end)
540 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
541 REG_NOTES (bb->end));
542 num_branches++;
543 }
544 }
545 /* Otherwise distribute the probabilities evenly so we get sane
546 sum. Use simple heuristics that if there are normal edges,
547 give all abnormals frequency of 0, otherwise distribute the
548 frequency over abnormals (this is the case of noreturn
549 calls). */
550 else
551 {
552 int total = 0;
553
554 for (e = bb->succ; e; e = e->succ_next)
555 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
556 total ++;
557 if (total)
558 {
559 for (e = bb->succ; e; e = e->succ_next)
560 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
561 e->probability = REG_BR_PROB_BASE / total;
562 else
563 e->probability = 0;
564 }
565 else
566 {
567 for (e = bb->succ; e; e = e->succ_next)
568 total ++;
569 for (e = bb->succ; e; e = e->succ_next)
570 e->probability = REG_BR_PROB_BASE / total;
571 }
572 if (bb->index >= 0
573 && any_condjump_p (bb->end)
574 && bb->succ->succ_next)
575 num_branches++, num_never_executed;
576 }
577 }
578
579 if (rtl_dump_file)
580 {
581 fprintf (rtl_dump_file, "%d branches\n", num_branches);
582 fprintf (rtl_dump_file, "%d branches never executed\n",
583 num_never_executed);
584 if (num_branches)
585 for (i = 0; i < 10; i++)
586 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
587 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
588 5 * i, 5 * i + 5);
589
590 total_num_branches += num_branches;
591 total_num_never_executed += num_never_executed;
592 for (i = 0; i < 20; i++)
593 total_hist_br_prob[i] += hist_br_prob[i];
594
595 fputc ('\n', rtl_dump_file);
596 fputc ('\n', rtl_dump_file);
597 }
598
599 free_aux_for_blocks ();
600 }
601
602 /* Instrument and/or analyze program behavior based on program flow graph.
603 In either case, this function builds a flow graph for the function being
604 compiled. The flow graph is stored in BB_GRAPH.
605
606 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
607 the flow graph that are needed to reconstruct the dynamic behavior of the
608 flow graph.
609
610 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
611 information from a data file containing edge count information from previous
612 executions of the function being compiled. In this case, the flow graph is
613 annotated with actual execution counts, which are later propagated into the
614 rtl for optimization purposes.
615
616 Main entry point of this file. */
617
618 void
619 branch_prob ()
620 {
621 basic_block bb;
622 unsigned i;
623 unsigned num_edges, ignored_edges;
624 unsigned num_instrumented;
625 struct edge_list *el;
626 unsigned n_values = 0;
627 struct histogram_value *values = NULL;
628
629 total_num_times_called++;
630
631 flow_call_edges_add (NULL);
632 add_noreturn_fake_exit_edges ();
633
634 /* We can't handle cyclic regions constructed using abnormal edges.
635 To avoid these we replace every source of abnormal edge by a fake
636 edge from entry node and every destination by fake edge to exit.
637 This keeps graph acyclic and our calculation exact for all normal
638 edges except for exit and entrance ones.
639
640 We also add fake exit edges for each call and asm statement in the
641 basic, since it may not return. */
642
643 FOR_EACH_BB (bb)
644 {
645 int need_exit_edge = 0, need_entry_edge = 0;
646 int have_exit_edge = 0, have_entry_edge = 0;
647 edge e;
648
649 /* Functions returning multiple times are not handled by extra edges.
650 Instead we simply allow negative counts on edges from exit to the
651 block past call and corresponding probabilities. We can't go
652 with the extra edges because that would result in flowgraph that
653 needs to have fake edges outside the spanning tree. */
654
655 for (e = bb->succ; e; e = e->succ_next)
656 {
657 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
658 && e->dest != EXIT_BLOCK_PTR)
659 need_exit_edge = 1;
660 if (e->dest == EXIT_BLOCK_PTR)
661 have_exit_edge = 1;
662 }
663 for (e = bb->pred; e; e = e->pred_next)
664 {
665 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
666 && e->src != ENTRY_BLOCK_PTR)
667 need_entry_edge = 1;
668 if (e->src == ENTRY_BLOCK_PTR)
669 have_entry_edge = 1;
670 }
671
672 if (need_exit_edge && !have_exit_edge)
673 {
674 if (rtl_dump_file)
675 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
676 bb->index);
677 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
678 }
679 if (need_entry_edge && !have_entry_edge)
680 {
681 if (rtl_dump_file)
682 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
683 bb->index);
684 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
685 }
686 }
687
688 el = create_edge_list ();
689 num_edges = NUM_EDGES (el);
690 alloc_aux_for_edges (sizeof (struct edge_info));
691
692 /* The basic blocks are expected to be numbered sequentially. */
693 compact_blocks ();
694
695 ignored_edges = 0;
696 for (i = 0 ; i < num_edges ; i++)
697 {
698 edge e = INDEX_EDGE (el, i);
699 e->count = 0;
700
701 /* Mark edges we've replaced by fake edges above as ignored. */
702 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
703 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
704 {
705 EDGE_INFO (e)->ignore = 1;
706 ignored_edges++;
707 }
708 }
709
710 #ifdef ENABLE_CHECKING
711 verify_flow_info ();
712 #endif
713
714 /* Create spanning tree from basic block graph, mark each edge that is
715 on the spanning tree. We insert as many abnormal and critical edges
716 as possible to minimize number of edge splits necessary. */
717
718 find_spanning_tree (el);
719
720 /* Fake edges that are not on the tree will not be instrumented, so
721 mark them ignored. */
722 for (num_instrumented = i = 0; i < num_edges; i++)
723 {
724 edge e = INDEX_EDGE (el, i);
725 struct edge_info *inf = EDGE_INFO (e);
726
727 if (inf->ignore || inf->on_tree)
728 /*NOP*/;
729 else if (e->flags & EDGE_FAKE)
730 {
731 inf->ignore = 1;
732 ignored_edges++;
733 }
734 else
735 num_instrumented++;
736 }
737
738 total_num_blocks += n_basic_blocks + 2;
739 if (rtl_dump_file)
740 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
741
742 total_num_edges += num_edges;
743 if (rtl_dump_file)
744 fprintf (rtl_dump_file, "%d edges\n", num_edges);
745
746 total_num_edges_ignored += ignored_edges;
747 if (rtl_dump_file)
748 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
749
750 /* Write the data from which gcov can reconstruct the basic block
751 graph. */
752
753 /* Basic block flags */
754 if (coverage_begin_output ())
755 {
756 gcov_position_t offset;
757
758 offset = gcov_write_tag (GCOV_TAG_BLOCKS);
759 for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
760 gcov_write_unsigned (0);
761 gcov_write_length (offset);
762 }
763
764 /* Keep all basic block indexes nonnegative in the gcov output.
765 Index 0 is used for entry block, last index is for exit block.
766 */
767 ENTRY_BLOCK_PTR->index = -1;
768 EXIT_BLOCK_PTR->index = last_basic_block;
769 #define BB_TO_GCOV_INDEX(bb) ((bb)->index + 1)
770
771 /* Arcs */
772 if (coverage_begin_output ())
773 {
774 gcov_position_t offset;
775
776 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
777 {
778 edge e;
779
780 offset = gcov_write_tag (GCOV_TAG_ARCS);
781 gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
782
783 for (e = bb->succ; e; e = e->succ_next)
784 {
785 struct edge_info *i = EDGE_INFO (e);
786 if (!i->ignore)
787 {
788 unsigned flag_bits = 0;
789
790 if (i->on_tree)
791 flag_bits |= GCOV_ARC_ON_TREE;
792 if (e->flags & EDGE_FAKE)
793 flag_bits |= GCOV_ARC_FAKE;
794 if (e->flags & EDGE_FALLTHRU)
795 flag_bits |= GCOV_ARC_FALLTHROUGH;
796
797 gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
798 gcov_write_unsigned (flag_bits);
799 }
800 }
801
802 gcov_write_length (offset);
803 }
804 }
805
806 /* Line numbers. */
807 if (coverage_begin_output ())
808 {
809 char const *prev_file_name = NULL;
810 gcov_position_t offset;
811
812 FOR_EACH_BB (bb)
813 {
814 rtx insn = bb->head;
815 int ignore_next_note = 0;
816
817 offset = 0;
818
819 /* We are looking for line number notes. Search backward
820 before basic block to find correct ones. */
821 insn = prev_nonnote_insn (insn);
822 if (!insn)
823 insn = get_insns ();
824 else
825 insn = NEXT_INSN (insn);
826
827 while (insn != bb->end)
828 {
829 if (GET_CODE (insn) == NOTE)
830 {
831 /* Must ignore the line number notes that
832 immediately follow the end of an inline function
833 to avoid counting it twice. There is a note
834 before the call, and one after the call. */
835 if (NOTE_LINE_NUMBER (insn)
836 == NOTE_INSN_REPEATED_LINE_NUMBER)
837 ignore_next_note = 1;
838 else if (NOTE_LINE_NUMBER (insn) <= 0)
839 /*NOP*/;
840 else if (ignore_next_note)
841 ignore_next_note = 0;
842 else
843 {
844 if (!offset)
845 {
846 offset = gcov_write_tag (GCOV_TAG_LINES);
847 gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
848 }
849
850 /* If this is a new source file, then output the
851 file's name to the .bb file. */
852 if (!prev_file_name
853 || strcmp (NOTE_SOURCE_FILE (insn),
854 prev_file_name))
855 {
856 prev_file_name = NOTE_SOURCE_FILE (insn);
857 gcov_write_unsigned (0);
858 gcov_write_string (prev_file_name);
859 }
860 gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
861 }
862 }
863 insn = NEXT_INSN (insn);
864 }
865
866 if (offset)
867 {
868 /* A file of NULL indicates the end of run. */
869 gcov_write_unsigned (0);
870 gcov_write_string (NULL);
871 gcov_write_length (offset);
872 }
873 }
874 }
875 ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
876 EXIT_BLOCK_PTR->index = EXIT_BLOCK;
877 #undef BB_TO_GCOV_INDEX
878
879 if (flag_profile_values)
880 {
881 life_analysis (get_insns (), NULL, PROP_DEATH_NOTES);
882 find_values_to_profile (&n_values, &values);
883 allocate_reg_info (max_reg_num (), FALSE, FALSE);
884 }
885
886 if (flag_branch_probabilities)
887 compute_branch_probabilities ();
888
889 /* For each edge not on the spanning tree, add counting code as rtl. */
890 if (profile_arc_flag
891 && coverage_counter_alloc (GCOV_COUNTER_ARCS, num_instrumented))
892 {
893 unsigned n_instrumented = instrument_edges (el);
894
895 if (n_instrumented != num_instrumented)
896 abort ();
897
898 if (flag_profile_values)
899 instrument_values (n_values, values);
900
901 /* Commit changes done by instrumentation. */
902 commit_edge_insertions_watch_calls ();
903 allocate_reg_info (max_reg_num (), FALSE, FALSE);
904 }
905
906 if (flag_profile_values)
907 count_or_remove_death_notes (NULL, 1);
908 remove_fake_edges ();
909 free_aux_for_edges ();
910 /* Re-merge split basic blocks and the mess introduced by
911 insert_insn_on_edge. */
912 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
913 if (rtl_dump_file)
914 dump_flow_info (rtl_dump_file);
915
916 free_edge_list (el);
917 }
918 \f
919 /* Union find algorithm implementation for the basic blocks using
920 aux fields. */
921
922 static basic_block
923 find_group (bb)
924 basic_block bb;
925 {
926 basic_block group = bb, bb1;
927
928 while ((basic_block) group->aux != group)
929 group = (basic_block) group->aux;
930
931 /* Compress path. */
932 while ((basic_block) bb->aux != group)
933 {
934 bb1 = (basic_block) bb->aux;
935 bb->aux = (void *) group;
936 bb = bb1;
937 }
938 return group;
939 }
940
941 static void
942 union_groups (bb1, bb2)
943 basic_block bb1, bb2;
944 {
945 basic_block bb1g = find_group (bb1);
946 basic_block bb2g = find_group (bb2);
947
948 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
949 this code is unlikely going to be performance problem anyway. */
950 if (bb1g == bb2g)
951 abort ();
952
953 bb1g->aux = bb2g;
954 }
955 \f
956 /* This function searches all of the edges in the program flow graph, and puts
957 as many bad edges as possible onto the spanning tree. Bad edges include
958 abnormals edges, which can't be instrumented at the moment. Since it is
959 possible for fake edges to form a cycle, we will have to develop some
960 better way in the future. Also put critical edges to the tree, since they
961 are more expensive to instrument. */
962
963 static void
964 find_spanning_tree (el)
965 struct edge_list *el;
966 {
967 int i;
968 int num_edges = NUM_EDGES (el);
969 basic_block bb;
970
971 /* We use aux field for standard union-find algorithm. */
972 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
973 bb->aux = bb;
974
975 /* Add fake edge exit to entry we can't instrument. */
976 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
977
978 /* First add all abnormal edges to the tree unless they form a cycle. Also
979 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
980 setting return value from function. */
981 for (i = 0; i < num_edges; i++)
982 {
983 edge e = INDEX_EDGE (el, i);
984 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
985 || e->dest == EXIT_BLOCK_PTR)
986 && !EDGE_INFO (e)->ignore
987 && (find_group (e->src) != find_group (e->dest)))
988 {
989 if (rtl_dump_file)
990 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
991 e->src->index, e->dest->index);
992 EDGE_INFO (e)->on_tree = 1;
993 union_groups (e->src, e->dest);
994 }
995 }
996
997 /* Now insert all critical edges to the tree unless they form a cycle. */
998 for (i = 0; i < num_edges; i++)
999 {
1000 edge e = INDEX_EDGE (el, i);
1001 if (EDGE_CRITICAL_P (e) && !EDGE_INFO (e)->ignore
1002 && find_group (e->src) != find_group (e->dest))
1003 {
1004 if (rtl_dump_file)
1005 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1006 e->src->index, e->dest->index);
1007 EDGE_INFO (e)->on_tree = 1;
1008 union_groups (e->src, e->dest);
1009 }
1010 }
1011
1012 /* And now the rest. */
1013 for (i = 0; i < num_edges; i++)
1014 {
1015 edge e = INDEX_EDGE (el, i);
1016 if (!EDGE_INFO (e)->ignore
1017 && find_group (e->src) != find_group (e->dest))
1018 {
1019 if (rtl_dump_file)
1020 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1021 e->src->index, e->dest->index);
1022 EDGE_INFO (e)->on_tree = 1;
1023 union_groups (e->src, e->dest);
1024 }
1025 }
1026
1027 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1028 bb->aux = NULL;
1029 }
1030 \f
1031 /* Perform file-level initialization for branch-prob processing. */
1032
1033 void
1034 init_branch_prob ()
1035 {
1036 int i;
1037
1038 total_num_blocks = 0;
1039 total_num_edges = 0;
1040 total_num_edges_ignored = 0;
1041 total_num_edges_instrumented = 0;
1042 total_num_blocks_created = 0;
1043 total_num_passes = 0;
1044 total_num_times_called = 0;
1045 total_num_branches = 0;
1046 total_num_never_executed = 0;
1047 for (i = 0; i < 20; i++)
1048 total_hist_br_prob[i] = 0;
1049 }
1050
1051 /* Performs file-level cleanup after branch-prob processing
1052 is completed. */
1053
1054 void
1055 end_branch_prob ()
1056 {
1057 if (rtl_dump_file)
1058 {
1059 fprintf (rtl_dump_file, "\n");
1060 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1061 total_num_blocks);
1062 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1063 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1064 total_num_edges_ignored);
1065 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1066 total_num_edges_instrumented);
1067 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1068 total_num_blocks_created);
1069 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1070 total_num_passes);
1071 if (total_num_times_called != 0)
1072 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1073 (total_num_passes + (total_num_times_called >> 1))
1074 / total_num_times_called);
1075 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1076 total_num_branches);
1077 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1078 total_num_never_executed);
1079 if (total_num_branches)
1080 {
1081 int i;
1082
1083 for (i = 0; i < 10; i++)
1084 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1085 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1086 / total_num_branches, 5*i, 5*i+5);
1087 }
1088 }
1089 }
1090
1091 \f
1092 /* Output instructions as RTL to increment the edge execution count. */
1093
1094 static rtx
1095 gen_edge_profiler (edgeno)
1096 int edgeno;
1097 {
1098 rtx ref = coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
1099 rtx tmp;
1100 enum machine_mode mode = GET_MODE (ref);
1101 rtx sequence;
1102
1103 start_sequence ();
1104 ref = validize_mem (ref);
1105
1106 tmp = expand_simple_binop (mode, PLUS, ref, const1_rtx,
1107 ref, 0, OPTAB_WIDEN);
1108
1109 if (tmp != ref)
1110 emit_move_insn (copy_rtx (ref), tmp);
1111
1112 sequence = get_insns ();
1113 end_sequence ();
1114 return sequence;
1115 }
1116
1117 /* Output instructions as RTL to increment the interval histogram counter.
1118 VALUE is the expression whose value is profiled. TAG is the tag of the
1119 section for counters, BASE is offset of the counter position. */
1120
1121 static rtx
1122 gen_interval_profiler (struct histogram_value *value,
1123 unsigned tag, unsigned base)
1124 {
1125 unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
1126 enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
1127 rtx mem_ref, tmp, tmp1, mr, val;
1128 rtx sequence;
1129 rtx more_label = gen_label_rtx ();
1130 rtx less_label = gen_label_rtx ();
1131 rtx end_of_code_label = gen_label_rtx ();
1132 int per_counter = gcov_size / BITS_PER_UNIT;
1133
1134 start_sequence ();
1135
1136 if (value->seq)
1137 emit_insn (value->seq);
1138
1139 mr = gen_reg_rtx (Pmode);
1140
1141 tmp = coverage_counter_ref (tag, base);
1142 tmp = force_reg (Pmode, XEXP (tmp, 0));
1143
1144 val = expand_simple_binop (value->mode, MINUS,
1145 copy_rtx (value->value),
1146 GEN_INT (value->hdata.intvl.int_start),
1147 NULL_RTX, 0, OPTAB_WIDEN);
1148
1149 if (value->hdata.intvl.may_be_more)
1150 do_compare_rtx_and_jump (copy_rtx (val), GEN_INT (value->hdata.intvl.steps),
1151 GE, 0, value->mode, NULL_RTX, NULL_RTX, more_label);
1152 if (value->hdata.intvl.may_be_less)
1153 do_compare_rtx_and_jump (copy_rtx (val), const0_rtx, LT, 0, value->mode,
1154 NULL_RTX, NULL_RTX, less_label);
1155
1156 /* We are in range. */
1157 tmp1 = expand_simple_binop (value->mode, MULT,
1158 copy_rtx (val), GEN_INT (per_counter),
1159 NULL_RTX, 0, OPTAB_WIDEN);
1160 tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp), tmp1, mr,
1161 0, OPTAB_WIDEN);
1162 if (tmp1 != mr)
1163 emit_move_insn (copy_rtx (mr), tmp1);
1164
1165 if (value->hdata.intvl.may_be_more
1166 || value->hdata.intvl.may_be_less)
1167 {
1168 emit_jump_insn (gen_jump (end_of_code_label));
1169 emit_barrier ();
1170 }
1171
1172 /* Above the interval. */
1173 if (value->hdata.intvl.may_be_more)
1174 {
1175 emit_label (more_label);
1176 tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
1177 GEN_INT (per_counter * value->hdata.intvl.steps),
1178 mr, 0, OPTAB_WIDEN);
1179 if (tmp1 != mr)
1180 emit_move_insn (copy_rtx (mr), tmp1);
1181 if (value->hdata.intvl.may_be_less)
1182 {
1183 emit_jump_insn (gen_jump (end_of_code_label));
1184 emit_barrier ();
1185 }
1186 }
1187
1188 /* Below the interval. */
1189 if (value->hdata.intvl.may_be_less)
1190 {
1191 emit_label (less_label);
1192 tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
1193 GEN_INT (per_counter * (value->hdata.intvl.steps
1194 + (value->hdata.intvl.may_be_more ? 1 : 0))),
1195 mr, 0, OPTAB_WIDEN);
1196 if (tmp1 != mr)
1197 emit_move_insn (copy_rtx (mr), tmp1);
1198 }
1199
1200 if (value->hdata.intvl.may_be_more
1201 || value->hdata.intvl.may_be_less)
1202 emit_label (end_of_code_label);
1203
1204 mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
1205
1206 tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
1207 mem_ref, 0, OPTAB_WIDEN);
1208
1209 if (tmp != mem_ref)
1210 emit_move_insn (copy_rtx (mem_ref), tmp);
1211
1212 sequence = get_insns ();
1213 end_sequence ();
1214 rebuild_jump_labels (sequence);
1215 return sequence;
1216 }
1217
1218 /* Output instructions as RTL to increment the power of two histogram counter.
1219 VALUE is the expression whose value is profiled. TAG is the tag of the
1220 section for counters, BASE is offset of the counter position. */
1221
1222 static rtx
1223 gen_pow2_profiler (struct histogram_value *value,
1224 unsigned tag, unsigned base)
1225 {
1226 unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
1227 enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
1228 rtx mem_ref, tmp, mr, uval;
1229 rtx sequence;
1230 rtx end_of_code_label = gen_label_rtx ();
1231 rtx loop_label = gen_label_rtx ();
1232 int per_counter = gcov_size / BITS_PER_UNIT;
1233
1234 start_sequence ();
1235
1236 if (value->seq)
1237 emit_insn (value->seq);
1238
1239 mr = gen_reg_rtx (Pmode);
1240 tmp = coverage_counter_ref (tag, base);
1241 tmp = force_reg (Pmode, XEXP (tmp, 0));
1242 emit_move_insn (mr, tmp);
1243
1244 uval = gen_reg_rtx (value->mode);
1245 emit_move_insn (uval, copy_rtx (value->value));
1246
1247 /* Check for non-power of 2. */
1248 if (value->hdata.pow2.may_be_other)
1249 {
1250 do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, LE, 0, value->mode,
1251 NULL_RTX, NULL_RTX, end_of_code_label);
1252 tmp = expand_simple_binop (value->mode, PLUS, copy_rtx (uval),
1253 constm1_rtx, NULL_RTX, 0, OPTAB_WIDEN);
1254 tmp = expand_simple_binop (value->mode, AND, copy_rtx (uval), tmp,
1255 NULL_RTX, 0, OPTAB_WIDEN);
1256 do_compare_rtx_and_jump (tmp, const0_rtx, NE, 0, value->mode, NULL_RTX,
1257 NULL_RTX, end_of_code_label);
1258 }
1259
1260 /* Count log_2(value). */
1261 emit_label (loop_label);
1262
1263 tmp = expand_simple_binop (Pmode, PLUS, copy_rtx (mr), GEN_INT (per_counter), mr, 0, OPTAB_WIDEN);
1264 if (tmp != mr)
1265 emit_move_insn (copy_rtx (mr), tmp);
1266
1267 tmp = expand_simple_binop (value->mode, ASHIFTRT, copy_rtx (uval), const1_rtx,
1268 uval, 0, OPTAB_WIDEN);
1269 if (tmp != uval)
1270 emit_move_insn (copy_rtx (uval), tmp);
1271
1272 do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, NE, 0, value->mode,
1273 NULL_RTX, NULL_RTX, loop_label);
1274
1275 /* Increase the counter. */
1276 emit_label (end_of_code_label);
1277
1278 mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
1279
1280 tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
1281 mem_ref, 0, OPTAB_WIDEN);
1282
1283 if (tmp != mem_ref)
1284 emit_move_insn (copy_rtx (mem_ref), tmp);
1285
1286 sequence = get_insns ();
1287 end_sequence ();
1288 rebuild_jump_labels (sequence);
1289 return sequence;
1290 }
1291
1292 /* Output instructions as RTL for code to find the most common value.
1293 VALUE is the expression whose value is profiled. TAG is the tag of the
1294 section for counters, BASE is offset of the counter position. */
1295
1296 static rtx
1297 gen_one_value_profiler (struct histogram_value *value,
1298 unsigned tag, unsigned base)
1299 {
1300 unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
1301 enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
1302 rtx stored_value_ref, counter_ref, all_ref, stored_value, counter, all;
1303 rtx tmp, uval;
1304 rtx sequence;
1305 rtx same_label = gen_label_rtx ();
1306 rtx zero_label = gen_label_rtx ();
1307 rtx end_of_code_label = gen_label_rtx ();
1308
1309 start_sequence ();
1310
1311 if (value->seq)
1312 emit_insn (value->seq);
1313
1314 stored_value_ref = coverage_counter_ref (tag, base);
1315 counter_ref = coverage_counter_ref (tag, base + 1);
1316 all_ref = coverage_counter_ref (tag, base + 2);
1317 stored_value = validize_mem (stored_value_ref);
1318 counter = validize_mem (counter_ref);
1319 all = validize_mem (all_ref);
1320
1321 uval = gen_reg_rtx (mode);
1322 convert_move (uval, copy_rtx (value->value), 0);
1323
1324 /* Check if the stored value matches. */
1325 do_compare_rtx_and_jump (copy_rtx (uval), copy_rtx (stored_value), EQ,
1326 0, mode, NULL_RTX, NULL_RTX, same_label);
1327
1328 /* Does not match; check whether the counter is zero. */
1329 do_compare_rtx_and_jump (copy_rtx (counter), const0_rtx, EQ, 0, mode,
1330 NULL_RTX, NULL_RTX, zero_label);
1331
1332 /* The counter is not zero yet. */
1333 tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), constm1_rtx,
1334 counter, 0, OPTAB_WIDEN);
1335
1336 if (tmp != counter)
1337 emit_move_insn (copy_rtx (counter), tmp);
1338
1339 emit_jump_insn (gen_jump (end_of_code_label));
1340 emit_barrier ();
1341
1342 emit_label (zero_label);
1343 /* Set new value. */
1344 emit_move_insn (copy_rtx (stored_value), copy_rtx (uval));
1345
1346 emit_label (same_label);
1347 /* Increase the counter. */
1348 tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), const1_rtx,
1349 counter, 0, OPTAB_WIDEN);
1350
1351 if (tmp != counter)
1352 emit_move_insn (copy_rtx (counter), tmp);
1353
1354 emit_label (end_of_code_label);
1355
1356 /* Increase the counter of all executions; this seems redundant given
1357 that ve have counts for edges in cfg, but it may happen that some
1358 optimization will change the counts for the block (either because
1359 it is unable to update them correctly, or because it will duplicate
1360 the block or its part). */
1361 tmp = expand_simple_binop (mode, PLUS, copy_rtx (all), const1_rtx,
1362 all, 0, OPTAB_WIDEN);
1363
1364 if (tmp != all)
1365 emit_move_insn (copy_rtx (all), tmp);
1366 sequence = get_insns ();
1367 end_sequence ();
1368 rebuild_jump_labels (sequence);
1369 return sequence;
1370 }
1371
1372 /* Output instructions as RTL for code to find the most common value of
1373 a difference between two evaluations of an expression.
1374 VALUE is the expression whose value is profiled. TAG is the tag of the
1375 section for counters, BASE is offset of the counter position. */
1376
1377 static rtx
1378 gen_const_delta_profiler (struct histogram_value *value,
1379 unsigned tag, unsigned base)
1380 {
1381 struct histogram_value one_value_delta;
1382 unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
1383 enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
1384 rtx stored_value_ref, stored_value, tmp, uval;
1385 rtx sequence;
1386
1387 start_sequence ();
1388
1389 if (value->seq)
1390 emit_insn (value->seq);
1391
1392 stored_value_ref = coverage_counter_ref (tag, base);
1393 stored_value = validize_mem (stored_value_ref);
1394
1395 uval = gen_reg_rtx (mode);
1396 convert_move (uval, copy_rtx (value->value), 0);
1397 tmp = expand_simple_binop (mode, MINUS,
1398 copy_rtx (uval), copy_rtx (stored_value),
1399 NULL_RTX, 0, OPTAB_WIDEN);
1400
1401 one_value_delta.value = tmp;
1402 one_value_delta.mode = mode;
1403 one_value_delta.seq = NULL_RTX;
1404 one_value_delta.insn = value->insn;
1405 one_value_delta.type = HIST_TYPE_SINGLE_VALUE;
1406 emit_insn (gen_one_value_profiler (&one_value_delta, tag, base + 1));
1407
1408 emit_move_insn (copy_rtx (stored_value), uval);
1409 sequence = get_insns ();
1410 end_sequence ();
1411 rebuild_jump_labels (sequence);
1412 return sequence;
1413 }