OSDN Git Service

* c-decl.c: Fix a comment typo.
[pf3gnuchains/gcc-fork.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  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 two auxiliary files generated are <dumpbase>.bb and
43    <dumpbase>.bbg. The former contains the BB->linenumber
44    mappings, and the latter describes the BB graph.
45
46    The BB file contains line numbers for each block. For each basic
47    block, a zero count is output (to mark the start of a block), then
48    the line numbers of that block are listed. A zero ends the file
49    too.
50
51    The BBG file contains a count of the blocks, followed by edge
52    information, for every edge in the graph. The edge information
53    lists the source and target block numbers, and a bit mask
54    describing the type of edge.
55
56    The BB and BBG file formats are fully described in the gcov
57    documentation.  */
58
59 /* ??? Register allocation should use basic block execution counts to
60    give preference to the most commonly executed blocks.  */
61
62 /* ??? The .da files are not safe.  Changing the program after creating .da
63    files or using different options when compiling with -fbranch-probabilities
64    can result the arc data not matching the program.  Maybe add instrumented
65    arc count to .bbg file?  Maybe check whether PFG matches the .bbg file?  */
66
67 /* ??? Should calculate branch probabilities before instrumenting code, since
68    then we can use arc counts to help decide which arcs to instrument.  */
69
70 #include "config.h"
71 #include "system.h"
72 #include "rtl.h"
73 #include "tree.h"
74 #include "flags.h"
75 #include "insn-config.h"
76 #include "output.h"
77 #include "regs.h"
78 #include "expr.h"
79 #include "function.h"
80 #include "toplev.h"
81 #include "ggc.h"
82 #include "hard-reg-set.h"
83 #include "basic-block.h"
84 #include "gcov-io.h"
85 #include "target.h"
86 #include "profile.h"
87 #include "libfuncs.h"
88 #include "langhooks.h"
89
90 /* Additional information about the edges we need.  */
91 struct edge_info {
92   unsigned int count_valid : 1;
93   
94   /* Is on the spanning tree.  */
95   unsigned int on_tree : 1;
96   
97   /* Pretend this edge does not exist (it is abnormal and we've
98      inserted a fake to compensate).  */
99   unsigned int ignore : 1;
100 };
101
102 struct bb_info {
103   unsigned int count_valid : 1;
104
105   /* Number of successor and predecessor edges.  */
106   gcov_type succ_count;
107   gcov_type pred_count;
108 };
109
110 #define EDGE_INFO(e)  ((struct edge_info *) (e)->aux)
111 #define BB_INFO(b)  ((struct bb_info *) (b)->aux)
112
113 /* Keep all basic block indexes nonnegative in the gcov output.  Index 0
114    is used for entry block, last block exit block.  */
115 #define BB_TO_GCOV_INDEX(bb)  ((bb) == ENTRY_BLOCK_PTR ? 0              \
116                                : ((bb) == EXIT_BLOCK_PTR                \
117                                   ? last_basic_block + 1 : (bb)->index + 1))
118
119 /* Instantiate the profile info structure.  */
120
121 struct profile_info profile_info;
122
123 /* Name and file pointer of the output file for the basic block graph.  */
124
125 static FILE *bbg_file;
126
127 /* Name and file pointer of the input file for the arc count data.  */
128
129 static FILE *da_file;
130 static char *da_file_name;
131
132 /* Pointer of the output file for the basic block/line number map.  */
133 static FILE *bb_file;
134
135 /* Last source file name written to bb_file.  */
136
137 static char *last_bb_file_name;
138
139 /* Collect statistics on the performance of this pass for the entire source
140    file.  */
141
142 static int total_num_blocks;
143 static int total_num_edges;
144 static int total_num_edges_ignored;
145 static int total_num_edges_instrumented;
146 static int total_num_blocks_created;
147 static int total_num_passes;
148 static int total_num_times_called;
149 static int total_hist_br_prob[20];
150 static int total_num_never_executed;
151 static int total_num_branches;
152
153 /* Forward declarations.  */
154 static void find_spanning_tree PARAMS ((struct edge_list *));
155 static void init_edge_profiler PARAMS ((void));
156 static rtx gen_edge_profiler PARAMS ((int));
157 static void instrument_edges PARAMS ((struct edge_list *));
158 static void output_gcov_string PARAMS ((const char *, long));
159 static void compute_branch_probabilities PARAMS ((void));
160 static gcov_type * get_exec_counts PARAMS ((void));
161 static long compute_checksum PARAMS ((void));
162 static basic_block find_group PARAMS ((basic_block));
163 static void union_groups PARAMS ((basic_block, basic_block));
164
165 /* If nonzero, we need to output a constructor to set up the
166    per-object-file data.  */
167 static int need_func_profiler = 0;
168 \f
169 /* Add edge instrumentation code to the entire insn chain.
170
171    F is the first insn of the chain.
172    NUM_BLOCKS is the number of basic blocks found in F.  */
173
174 static void
175 instrument_edges (el)
176      struct edge_list *el;
177 {
178   int num_instr_edges = 0;
179   int num_edges = NUM_EDGES (el);
180   basic_block bb;
181   remove_fake_edges ();
182
183   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
184     {
185       edge e = bb->succ;
186       while (e)
187         {
188           struct edge_info *inf = EDGE_INFO (e);
189           if (!inf->ignore && !inf->on_tree)
190             {
191               if (e->flags & EDGE_ABNORMAL)
192                 abort ();
193               if (rtl_dump_file)
194                 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
195                          e->src->index, e->dest->index,
196                          EDGE_CRITICAL_P (e) ? " (and split)" : "");
197               need_func_profiler = 1;
198               insert_insn_on_edge (
199                          gen_edge_profiler (total_num_edges_instrumented
200                                             + num_instr_edges++), e);
201             }
202           e = e->succ_next;
203         }
204     }
205
206   profile_info.count_edges_instrumented_now = num_instr_edges;
207   total_num_edges_instrumented += num_instr_edges;
208   profile_info.count_instrumented_edges = total_num_edges_instrumented;
209
210   total_num_blocks_created += num_edges;
211   if (rtl_dump_file)
212     fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
213
214   commit_edge_insertions_watch_calls ();
215 }
216
217 /* Output STRING to bb_file, surrounded by DELIMITER.  */
218
219 static void
220 output_gcov_string (string, delimiter)
221      const char *string;
222      long delimiter;
223 {
224   size_t temp;
225
226   /* Write a delimiter to indicate that a file name follows.  */
227   __write_long (delimiter, bb_file, 4);
228
229   /* Write the string.  */
230   temp = strlen (string) + 1;
231   fwrite (string, temp, 1, bb_file);
232
233   /* Append a few zeros, to align the output to a 4 byte boundary.  */
234   temp = temp & 0x3;
235   if (temp)
236     {
237       char c[4];
238
239       c[0] = c[1] = c[2] = c[3] = 0;
240       fwrite (c, sizeof (char), 4 - temp, bb_file);
241     }
242
243   /* Store another delimiter in the .bb file, just to make it easy to find
244      the end of the file name.  */
245   __write_long (delimiter, bb_file, 4);
246 }
247 \f
248
249 /* Computes hybrid profile for all matching entries in da_file.
250    Sets max_counter_in_program as a side effect.  */
251
252 static gcov_type *
253 get_exec_counts ()
254 {
255   int num_edges = 0;
256   basic_block bb;
257   int okay = 1, i;
258   int mismatch = 0;
259   gcov_type *profile;
260   char *function_name_buffer;
261   int function_name_buffer_len;
262   gcov_type max_counter_in_run;
263   const char *name = IDENTIFIER_POINTER
264                       (DECL_ASSEMBLER_NAME (current_function_decl));
265
266   profile_info.max_counter_in_program = 0;
267   profile_info.count_profiles_merged = 0;
268
269   /* No .da file, no execution counts.  */
270   if (!da_file)
271     return 0;
272
273   /* Count the edges to be (possibly) instrumented.  */
274
275   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
276     {
277       edge e;
278       for (e = bb->succ; e; e = e->succ_next)
279         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
280           num_edges++;
281     }
282
283   /* now read and combine all matching profiles.  */
284
285   profile = xmalloc (sizeof (gcov_type) * num_edges);
286   rewind (da_file);
287   function_name_buffer_len = strlen (name) + 1;
288   function_name_buffer = xmalloc (function_name_buffer_len + 1);
289
290   for (i = 0; i < num_edges; i++)
291     profile[i] = 0;
292
293   while (1)
294     {
295       long magic, extra_bytes;
296       long func_count;
297       int i;
298
299       if (__read_long (&magic, da_file, 4) != 0)
300         break;
301
302       if (magic != -123)
303         {
304           okay = 0;
305           break;
306         }
307
308       if (__read_long (&func_count, da_file, 4) != 0)
309         {
310           okay = 0;
311           break;
312         }
313
314       if (__read_long (&extra_bytes, da_file, 4) != 0)
315         {
316           okay = 0;
317           break;
318         }
319
320       fseek (da_file, 4 + 8, SEEK_CUR);
321
322       /* read the maximal counter.  */
323       __read_gcov_type (&max_counter_in_run, da_file, 8);
324
325       /* skip the rest of "statistics" emited by __bb_exit_func.  */
326       fseek (da_file, extra_bytes - (4 + 8 + 8), SEEK_CUR);
327
328       for (i = 0; i < func_count; i++)
329         {
330           long arc_count;
331           long chksum;
332           int j;
333
334           if (__read_gcov_string
335               (function_name_buffer, function_name_buffer_len, da_file,
336                -1) != 0)
337             {
338               okay = 0;
339               break;
340             }
341
342           if (__read_long (&chksum, da_file, 4) != 0)
343             {
344               okay = 0;
345               break;
346             }
347
348           if (__read_long (&arc_count, da_file, 4) != 0)
349             {
350               okay = 0;
351               break;
352             }
353
354           if (strcmp (function_name_buffer, name) != 0)
355             {
356               /* skip */
357               if (fseek (da_file, arc_count * 8, SEEK_CUR) < 0)
358                 {
359                   okay = 0;
360                   break;
361                 }
362             }
363           else if (arc_count != num_edges
364                    || chksum != profile_info.current_function_cfg_checksum)
365             okay = 0, mismatch = 1;
366           else
367             {
368               gcov_type tmp;
369
370               profile_info.max_counter_in_program += max_counter_in_run;
371               profile_info.count_profiles_merged++;
372
373               for (j = 0; j < arc_count; j++)
374                 if (__read_gcov_type (&tmp, da_file, 8) != 0)
375                   {
376                     okay = 0;
377                     break;
378                   }
379                 else
380                   {
381                     profile[j] += tmp;
382                   }
383             }
384         }
385
386       if (!okay)
387         break;
388
389     }
390
391   free (function_name_buffer);
392
393   if (!okay)
394     {
395       if (mismatch)
396         error
397           ("Profile does not match flowgraph of function %s (out of date?)",
398            current_function_name);
399       else
400         error (".da file corrupted");
401       free (profile);
402       return 0;
403     }
404   if (rtl_dump_file)
405     {
406       fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
407               profile_info.count_profiles_merged,
408               (int)profile_info.max_counter_in_program);
409     }
410
411   return profile;
412 }
413 \f
414
415 /* Compute the branch probabilities for the various branches.
416    Annotate them accordingly.  */
417
418 static void
419 compute_branch_probabilities ()
420 {
421   basic_block bb;
422   int i;
423   int num_edges = 0;
424   int changes;
425   int passes;
426   int hist_br_prob[20];
427   int num_never_executed;
428   int num_branches;
429   gcov_type *exec_counts = get_exec_counts ();
430   int exec_counts_pos = 0;
431
432   /* Attach extra info block to each bb.  */
433
434   alloc_aux_for_blocks (sizeof (struct bb_info));
435   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
436     {
437       edge e;
438
439       for (e = bb->succ; e; e = e->succ_next)
440         if (!EDGE_INFO (e)->ignore)
441           BB_INFO (bb)->succ_count++;
442       for (e = bb->pred; e; e = e->pred_next)
443         if (!EDGE_INFO (e)->ignore)
444           BB_INFO (bb)->pred_count++;
445     }
446
447   /* Avoid predicting entry on exit nodes.  */
448   BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
449   BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
450
451   /* For each edge not on the spanning tree, set its execution count from
452      the .da file.  */
453
454   /* The first count in the .da file is the number of times that the function
455      was entered.  This is the exec_count for block zero.  */
456
457   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
458     {
459       edge e;
460       for (e = bb->succ; e; e = e->succ_next)
461         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
462           {
463             num_edges++;
464             if (exec_counts)
465               {
466                 e->count = exec_counts[exec_counts_pos++];
467               }
468             else
469               e->count = 0;
470
471             EDGE_INFO (e)->count_valid = 1;
472             BB_INFO (bb)->succ_count--;
473             BB_INFO (e->dest)->pred_count--;
474             if (rtl_dump_file)
475               {
476                 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
477                          bb->index, e->dest->index);
478                 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
479                          (HOST_WIDEST_INT) e->count);
480               }
481           }
482     }
483
484   if (rtl_dump_file)
485     fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
486
487   /* For every block in the file,
488      - if every exit/entrance edge has a known count, then set the block count
489      - if the block count is known, and every exit/entrance edge but one has
490      a known execution count, then set the count of the remaining edge
491
492      As edge counts are set, decrement the succ/pred count, but don't delete
493      the edge, that way we can easily tell when all edges are known, or only
494      one edge is unknown.  */
495
496   /* The order that the basic blocks are iterated through is important.
497      Since the code that finds spanning trees starts with block 0, low numbered
498      edges are put on the spanning tree in preference to high numbered edges.
499      Hence, most instrumented edges are at the end.  Graph solving works much
500      faster if we propagate numbers from the end to the start.
501
502      This takes an average of slightly more than 3 passes.  */
503
504   changes = 1;
505   passes = 0;
506   while (changes)
507     {
508       passes++;
509       changes = 0;
510       FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
511         {
512           struct bb_info *bi = BB_INFO (bb);
513           if (! bi->count_valid)
514             {
515               if (bi->succ_count == 0)
516                 {
517                   edge e;
518                   gcov_type total = 0;
519
520                   for (e = bb->succ; e; e = e->succ_next)
521                     total += e->count;
522                   bb->count = total;
523                   bi->count_valid = 1;
524                   changes = 1;
525                 }
526               else if (bi->pred_count == 0)
527                 {
528                   edge e;
529                   gcov_type total = 0;
530
531                   for (e = bb->pred; e; e = e->pred_next)
532                     total += e->count;
533                   bb->count = total;
534                   bi->count_valid = 1;
535                   changes = 1;
536                 }
537             }
538           if (bi->count_valid)
539             {
540               if (bi->succ_count == 1)
541                 {
542                   edge e;
543                   gcov_type total = 0;
544
545                   /* One of the counts will be invalid, but it is zero,
546                      so adding it in also doesn't hurt.  */
547                   for (e = bb->succ; e; e = e->succ_next)
548                     total += e->count;
549
550                   /* Seedgeh for the invalid edge, and set its count.  */
551                   for (e = bb->succ; e; e = e->succ_next)
552                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
553                       break;
554
555                   /* Calculate count for remaining edge by conservation.  */
556                   total = bb->count - total;
557
558                   if (! e)
559                     abort ();
560                   EDGE_INFO (e)->count_valid = 1;
561                   e->count = total;
562                   bi->succ_count--;
563
564                   BB_INFO (e->dest)->pred_count--;
565                   changes = 1;
566                 }
567               if (bi->pred_count == 1)
568                 {
569                   edge e;
570                   gcov_type total = 0;
571
572                   /* One of the counts will be invalid, but it is zero,
573                      so adding it in also doesn't hurt.  */
574                   for (e = bb->pred; e; e = e->pred_next)
575                     total += e->count;
576
577                   /* Seedgeh for the invalid edge, and set its count.  */
578                   for (e = bb->pred; e; e = e->pred_next)
579                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
580                       break;
581
582                   /* Calculate count for remaining edge by conservation.  */
583                   total = bb->count - total + e->count;
584
585                   if (! e)
586                     abort ();
587                   EDGE_INFO (e)->count_valid = 1;
588                   e->count = total;
589                   bi->pred_count--;
590
591                   BB_INFO (e->src)->succ_count--;
592                   changes = 1;
593                 }
594             }
595         }
596     }
597   if (rtl_dump_file)
598     dump_flow_info (rtl_dump_file);
599
600   total_num_passes += passes;
601   if (rtl_dump_file)
602     fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
603
604   /* If the graph has been correctly solved, every block will have a
605      succ and pred count of zero.  */
606   FOR_EACH_BB (bb)
607     {
608       if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
609         abort ();
610     }
611
612   /* For every edge, calculate its branch probability and add a reg_note
613      to the branch insn to indicate this.  */
614
615   for (i = 0; i < 20; i++)
616     hist_br_prob[i] = 0;
617   num_never_executed = 0;
618   num_branches = 0;
619
620   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
621     {
622       edge e;
623       gcov_type total;
624       rtx note;
625
626       total = bb->count;
627       if (total)
628         {
629           for (e = bb->succ; e; e = e->succ_next)
630             {
631                 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
632                 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
633                   {
634                     error ("corrupted profile info: prob for %d-%d thought to be %d",
635                            e->src->index, e->dest->index, e->probability);
636                     e->probability = REG_BR_PROB_BASE / 2;
637                   }
638             }
639           if (bb->index >= 0
640               && any_condjump_p (bb->end)
641               && bb->succ->succ_next)
642             {
643               int prob;
644               edge e;
645               int index;
646
647               /* Find the branch edge.  It is possible that we do have fake
648                  edges here.  */
649               for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
650                    e = e->succ_next)
651                 continue; /* Loop body has been intentionally left blank.  */
652
653               prob = e->probability;
654               index = prob * 20 / REG_BR_PROB_BASE;
655
656               if (index == 20)
657                 index = 19;
658               hist_br_prob[index]++;
659
660               note = find_reg_note (bb->end, REG_BR_PROB, 0);
661               /* There may be already note put by some other pass, such
662                  as builtin_expect expander.  */
663               if (note)
664                 XEXP (note, 0) = GEN_INT (prob);
665               else
666                 REG_NOTES (bb->end)
667                   = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
668                                        REG_NOTES (bb->end));
669               num_branches++;
670             }
671         }
672       /* Otherwise distribute the probabilities evenly so we get sane sum.
673          Use simple heuristics that if there are normal edges, give all abnormals
674          frequency of 0, otherwise distribute the frequency over abnormals
675          (this is the case of noreturn calls).  */
676       else
677         {
678           for (e = bb->succ; e; e = e->succ_next)
679             if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
680               total ++;
681           if (total)
682             {
683               for (e = bb->succ; e; e = e->succ_next)
684                 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
685                   e->probability = REG_BR_PROB_BASE / total;
686                 else
687                   e->probability = 0;
688             }
689           else
690             {
691               for (e = bb->succ; e; e = e->succ_next)
692                 total ++;
693               for (e = bb->succ; e; e = e->succ_next)
694                 e->probability = REG_BR_PROB_BASE / total;
695             }
696           if (bb->index >= 0
697               && any_condjump_p (bb->end)
698               && bb->succ->succ_next)
699             num_branches++, num_never_executed;
700         }
701     }
702
703   if (rtl_dump_file)
704     {
705       fprintf (rtl_dump_file, "%d branches\n", num_branches);
706       fprintf (rtl_dump_file, "%d branches never executed\n",
707                num_never_executed);
708       if (num_branches)
709         for (i = 0; i < 10; i++)
710           fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
711                    (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
712                    5 * i, 5 * i + 5);
713
714       total_num_branches += num_branches;
715       total_num_never_executed += num_never_executed;
716       for (i = 0; i < 20; i++)
717         total_hist_br_prob[i] += hist_br_prob[i];
718
719       fputc ('\n', rtl_dump_file);
720       fputc ('\n', rtl_dump_file);
721     }
722
723   free_aux_for_blocks ();
724   if (exec_counts)
725     free (exec_counts);
726 }
727
728 /* Compute checksum for the current function.  */
729
730 #define CHSUM_HASH      500000003
731 #define CHSUM_SHIFT     2
732
733 static long
734 compute_checksum ()
735 {
736   long chsum = 0;
737   basic_block bb;
738
739   FOR_EACH_BB (bb)
740     {
741       edge e;
742
743       for (e = bb->succ; e; e = e->succ_next)
744         {
745           chsum = ((chsum << CHSUM_SHIFT) + (BB_TO_GCOV_INDEX (e->dest) + 1)) % CHSUM_HASH;
746         }
747
748       chsum = (chsum << CHSUM_SHIFT) % CHSUM_HASH;
749     }
750
751   return chsum;
752 }
753
754 /* Instrument and/or analyze program behavior based on program flow graph.
755    In either case, this function builds a flow graph for the function being
756    compiled.  The flow graph is stored in BB_GRAPH.
757
758    When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
759    the flow graph that are needed to reconstruct the dynamic behavior of the
760    flow graph.
761
762    When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
763    information from a data file containing edge count information from previous
764    executions of the function being compiled.  In this case, the flow graph is
765    annotated with actual execution counts, which are later propagated into the
766    rtl for optimization purposes.
767
768    Main entry point of this file.  */
769
770 void
771 branch_prob ()
772 {
773   basic_block bb;
774   int i;
775   int num_edges, ignored_edges;
776   struct edge_list *el;
777   const char *name = IDENTIFIER_POINTER
778                        (DECL_ASSEMBLER_NAME (current_function_decl));
779
780   profile_info.current_function_cfg_checksum = compute_checksum ();
781
782   if (rtl_dump_file)
783     fprintf (rtl_dump_file, "CFG checksum is %ld\n",
784         profile_info.current_function_cfg_checksum);
785
786   /* Start of a function.  */
787   if (flag_test_coverage)
788     output_gcov_string (name, (long) -2);
789
790   total_num_times_called++;
791
792   flow_call_edges_add (NULL);
793   add_noreturn_fake_exit_edges ();
794
795   /* We can't handle cyclic regions constructed using abnormal edges.
796      To avoid these we replace every source of abnormal edge by a fake
797      edge from entry node and every destination by fake edge to exit.
798      This keeps graph acyclic and our calculation exact for all normal
799      edges except for exit and entrance ones.
800
801      We also add fake exit edges for each call and asm statement in the
802      basic, since it may not return.  */
803
804   FOR_EACH_BB (bb)
805     {
806       int need_exit_edge = 0, need_entry_edge = 0;
807       int have_exit_edge = 0, have_entry_edge = 0;
808       rtx insn;
809       edge e;
810
811       /* Add fake edges from entry block to the call insns that may return
812          twice.  The CFG is not quite correct then, as call insn plays more
813          role of CODE_LABEL, but for our purposes, everything should be OK,
814          as we never insert code to the beggining of basic block.  */
815       for (insn = bb->head; insn != NEXT_INSN (bb->end);
816            insn = NEXT_INSN (insn))
817         {
818           if (GET_CODE (insn) == CALL_INSN
819               && find_reg_note (insn, REG_SETJMP, NULL))
820             {
821               if (GET_CODE (bb->head) == CODE_LABEL
822                   || insn != NEXT_INSN (bb->head))
823                 {
824                   e = split_block (bb, PREV_INSN (insn));
825                   make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
826                   break;
827                 }
828               else
829                 {
830                   /* We should not get abort here, as call to setjmp should not
831                      be the very first instruction of function.  */
832                   if (bb == ENTRY_BLOCK_PTR)
833                     abort ();
834                   make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
835                 }
836             }
837         }
838
839       for (e = bb->succ; e; e = e->succ_next)
840         {
841           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
842                && e->dest != EXIT_BLOCK_PTR)
843             need_exit_edge = 1;
844           if (e->dest == EXIT_BLOCK_PTR)
845             have_exit_edge = 1;
846         }
847       for (e = bb->pred; e; e = e->pred_next)
848         {
849           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
850                && e->src != ENTRY_BLOCK_PTR)
851             need_entry_edge = 1;
852           if (e->src == ENTRY_BLOCK_PTR)
853             have_entry_edge = 1;
854         }
855
856       if (need_exit_edge && !have_exit_edge)
857         {
858           if (rtl_dump_file)
859             fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
860                      bb->index);
861           make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
862         }
863       if (need_entry_edge && !have_entry_edge)
864         {
865           if (rtl_dump_file)
866             fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
867                      bb->index);
868           make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
869         }
870     }
871
872   el = create_edge_list ();
873   num_edges = NUM_EDGES (el);
874   alloc_aux_for_edges (sizeof (struct edge_info));
875
876   /* The basic blocks are expected to be numbered sequentially.  */
877   compact_blocks ();
878
879   ignored_edges = 0;
880   for (i = 0 ; i < num_edges ; i++)
881     {
882       edge e = INDEX_EDGE (el, i);
883       e->count = 0;
884
885       /* Mark edges we've replaced by fake edges above as ignored.  */
886       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
887           && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
888         {
889           EDGE_INFO (e)->ignore = 1;
890           ignored_edges++;
891         }
892     }
893
894 #ifdef ENABLE_CHECKING
895   verify_flow_info ();
896 #endif
897
898   /* Output line number information about each basic block for
899      GCOV utility.  */
900   if (flag_test_coverage)
901     {
902       FOR_EACH_BB (bb)
903         {
904           rtx insn = bb->head;
905           static int ignore_next_note = 0;
906
907           /* We are looking for line number notes.  Search backward before
908              basic block to find correct ones.  */
909           insn = prev_nonnote_insn (insn);
910           if (!insn)
911             insn = get_insns ();
912           else
913             insn = NEXT_INSN (insn);
914
915           /* Output a zero to the .bb file to indicate that a new
916              block list is starting.  */
917           __write_long (0, bb_file, 4);
918
919           while (insn != bb->end)
920             {
921               if (GET_CODE (insn) == NOTE)
922                 {
923                   /* Must ignore the line number notes that immediately
924                      follow the end of an inline function to avoid counting
925                      it twice.  There is a note before the call, and one
926                      after the call.  */
927                   if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_REPEATED_LINE_NUMBER)
928                     ignore_next_note = 1;
929                   else if (NOTE_LINE_NUMBER (insn) > 0)
930                     {
931                       if (ignore_next_note)
932                         ignore_next_note = 0;
933                       else
934                         {
935                           /* If this is a new source file, then output the
936                              file's name to the .bb file.  */
937                           if (! last_bb_file_name
938                               || strcmp (NOTE_SOURCE_FILE (insn),
939                                          last_bb_file_name))
940                             {
941                               if (last_bb_file_name)
942                                 free (last_bb_file_name);
943                               last_bb_file_name
944                                 = xstrdup (NOTE_SOURCE_FILE (insn));
945                               output_gcov_string (NOTE_SOURCE_FILE (insn),
946                                                   (long)-1);
947                             }
948                           /* Output the line number to the .bb file.  Must be
949                              done after the output_bb_profile_data() call, and
950                              after the file name is written, to ensure that it
951                              is correctly handled by gcov.  */
952                           __write_long (NOTE_LINE_NUMBER (insn), bb_file, 4);
953                         }
954                     }
955                 }
956               insn = NEXT_INSN (insn);
957             }
958         }
959       __write_long (0, bb_file, 4);
960     }
961
962   /* Create spanning tree from basic block graph, mark each edge that is
963      on the spanning tree.  We insert as many abnormal and critical edges
964      as possible to minimize number of edge splits necessary.  */
965
966   find_spanning_tree (el);
967
968   /* Fake edges that are not on the tree will not be instrumented, so
969      mark them ignored.  */
970   for (i = 0; i < num_edges; i++)
971     {
972       edge e = INDEX_EDGE (el, i);
973       struct edge_info *inf = EDGE_INFO (e);
974       if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
975         {
976           inf->ignore = 1;
977           ignored_edges++;
978         }
979     }
980
981   total_num_blocks += n_basic_blocks + 2;
982   if (rtl_dump_file)
983     fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
984
985   total_num_edges += num_edges;
986   if (rtl_dump_file)
987     fprintf (rtl_dump_file, "%d edges\n", num_edges);
988
989   total_num_edges_ignored += ignored_edges;
990   if (rtl_dump_file)
991     fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
992
993   /* Create a .bbg file from which gcov can reconstruct the basic block
994      graph.  First output the number of basic blocks, and then for every
995      edge output the source and target basic block numbers.
996      NOTE: The format of this file must be compatible with gcov.  */
997
998   if (flag_test_coverage)
999     {
1000       int flag_bits;
1001
1002       __write_gcov_string (name, strlen (name), bbg_file, -1);
1003
1004       /* write checksum.  */
1005       __write_long (profile_info.current_function_cfg_checksum, bbg_file, 4);
1006
1007       /* The plus 2 stands for entry and exit block.  */
1008       __write_long (n_basic_blocks + 2, bbg_file, 4);
1009       __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
1010
1011       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1012         {
1013           edge e;
1014           long count = 0;
1015
1016           for (e = bb->succ; e; e = e->succ_next)
1017             if (!EDGE_INFO (e)->ignore)
1018               count++;
1019           __write_long (count, bbg_file, 4);
1020
1021           for (e = bb->succ; e; e = e->succ_next)
1022             {
1023               struct edge_info *i = EDGE_INFO (e);
1024               if (!i->ignore)
1025                 {
1026                   flag_bits = 0;
1027                   if (i->on_tree)
1028                     flag_bits |= 0x1;
1029                   if (e->flags & EDGE_FAKE)
1030                     flag_bits |= 0x2;
1031                   if (e->flags & EDGE_FALLTHRU)
1032                     flag_bits |= 0x4;
1033
1034                   __write_long (BB_TO_GCOV_INDEX (e->dest), bbg_file, 4);
1035                   __write_long (flag_bits, bbg_file, 4);
1036                 }
1037             }
1038         }
1039       /* Emit fake loopback edge for EXIT block to maintain compatibility with
1040          old gcov format.  */
1041       __write_long (1, bbg_file, 4);
1042       __write_long (0, bbg_file, 4);
1043       __write_long (0x1, bbg_file, 4);
1044
1045       /* Emit a -1 to separate the list of all edges from the list of
1046          loop back edges that follows.  */
1047       __write_long (-1, bbg_file, 4);
1048     }
1049
1050   if (flag_branch_probabilities)
1051     compute_branch_probabilities ();
1052
1053   /* For each edge not on the spanning tree, add counting code as rtl.  */
1054
1055   if (profile_arc_flag)
1056     {
1057       instrument_edges (el);
1058       allocate_reg_info (max_reg_num (), FALSE, FALSE);
1059     }
1060
1061   remove_fake_edges ();
1062   /* Re-merge split basic blocks and the mess introduced by
1063      insert_insn_on_edge.  */
1064   cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1065   if (rtl_dump_file)
1066     dump_flow_info (rtl_dump_file);
1067
1068   free_aux_for_edges ();
1069   free_edge_list (el);
1070 }
1071 \f
1072 /* Union find algorithm implementation for the basic blocks using
1073    aux fields.  */
1074
1075 static basic_block
1076 find_group (bb)
1077      basic_block bb;
1078 {
1079   basic_block group = bb, bb1;
1080
1081   while ((basic_block) group->aux != group)
1082     group = (basic_block) group->aux;
1083
1084   /* Compress path.  */
1085   while ((basic_block) bb->aux != group)
1086     {
1087       bb1 = (basic_block) bb->aux;
1088       bb->aux = (void *) group;
1089       bb = bb1;
1090     }
1091   return group;
1092 }
1093
1094 static void
1095 union_groups (bb1, bb2)
1096      basic_block bb1, bb2;
1097 {
1098   basic_block bb1g = find_group (bb1);
1099   basic_block bb2g = find_group (bb2);
1100
1101   /* ??? I don't have a place for the rank field.  OK.  Lets go w/o it,
1102      this code is unlikely going to be performance problem anyway.  */
1103   if (bb1g == bb2g)
1104     abort ();
1105
1106   bb1g->aux = bb2g;
1107 }
1108 \f
1109 /* This function searches all of the edges in the program flow graph, and puts
1110    as many bad edges as possible onto the spanning tree.  Bad edges include
1111    abnormals edges, which can't be instrumented at the moment.  Since it is
1112    possible for fake edges to form a cycle, we will have to develop some
1113    better way in the future.  Also put critical edges to the tree, since they
1114    are more expensive to instrument.  */
1115
1116 static void
1117 find_spanning_tree (el)
1118      struct edge_list *el;
1119 {
1120   int i;
1121   int num_edges = NUM_EDGES (el);
1122   basic_block bb;
1123
1124   /* We use aux field for standard union-find algorithm.  */
1125   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1126     bb->aux = bb;
1127
1128   /* Add fake edge exit to entry we can't instrument.  */
1129   union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1130
1131   /* First add all abnormal edges to the tree unless they form a cycle. Also
1132      add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1133      setting return value from function.  */
1134   for (i = 0; i < num_edges; i++)
1135     {
1136       edge e = INDEX_EDGE (el, i);
1137       if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1138            || e->dest == EXIT_BLOCK_PTR
1139            )
1140           && !EDGE_INFO (e)->ignore
1141           && (find_group (e->src) != find_group (e->dest)))
1142         {
1143           if (rtl_dump_file)
1144             fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1145                      e->src->index, e->dest->index);
1146           EDGE_INFO (e)->on_tree = 1;
1147           union_groups (e->src, e->dest);
1148         }
1149     }
1150
1151   /* Now insert all critical edges to the tree unless they form a cycle.  */
1152   for (i = 0; i < num_edges; i++)
1153     {
1154       edge e = INDEX_EDGE (el, i);
1155       if ((EDGE_CRITICAL_P (e))
1156           && !EDGE_INFO (e)->ignore
1157           && (find_group (e->src) != find_group (e->dest)))
1158         {
1159           if (rtl_dump_file)
1160             fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1161                      e->src->index, e->dest->index);
1162           EDGE_INFO (e)->on_tree = 1;
1163           union_groups (e->src, e->dest);
1164         }
1165     }
1166
1167   /* And now the rest.  */
1168   for (i = 0; i < num_edges; i++)
1169     {
1170       edge e = INDEX_EDGE (el, i);
1171       if (find_group (e->src) != find_group (e->dest)
1172           && !EDGE_INFO (e)->ignore)
1173         {
1174           if (rtl_dump_file)
1175             fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1176                      e->src->index, e->dest->index);
1177           EDGE_INFO (e)->on_tree = 1;
1178           union_groups (e->src, e->dest);
1179         }
1180     }
1181
1182   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1183     bb->aux = NULL;
1184 }
1185 \f
1186 /* Perform file-level initialization for branch-prob processing.  */
1187
1188 void
1189 init_branch_prob (filename)
1190   const char *filename;
1191 {
1192   int len = strlen (filename);
1193   int i;
1194
1195   if (flag_test_coverage)
1196     {
1197       char *data_file, *bbg_file_name;
1198
1199       /* Open an output file for the basic block/line number map.  */
1200       data_file = (char *) alloca (len + 4);
1201       strcpy (data_file, filename);
1202       strcat (data_file, ".bb");
1203       if ((bb_file = fopen (data_file, "wb")) == 0)
1204         fatal_io_error ("can't open %s", data_file);
1205
1206       /* Open an output file for the program flow graph.  */
1207       bbg_file_name = (char *) alloca (len + 5);
1208       strcpy (bbg_file_name, filename);
1209       strcat (bbg_file_name, ".bbg");
1210       if ((bbg_file = fopen (bbg_file_name, "wb")) == 0)
1211         fatal_io_error ("can't open %s", bbg_file_name);
1212
1213       /* Initialize to zero, to ensure that the first file name will be
1214          written to the .bb file.  */
1215       last_bb_file_name = 0;
1216     }
1217
1218   da_file_name = (char *) xmalloc (len + 4);
1219   strcpy (da_file_name, filename);
1220   strcat (da_file_name, ".da");
1221   
1222   if (flag_branch_probabilities)
1223     {
1224       da_file = fopen (da_file_name, "rb");
1225       if (!da_file)
1226         warning ("file %s not found, execution counts assumed to be zero",
1227                  da_file_name);
1228     }
1229
1230   if (profile_arc_flag)
1231     init_edge_profiler ();
1232
1233   total_num_blocks = 0;
1234   total_num_edges = 0;
1235   total_num_edges_ignored = 0;
1236   total_num_edges_instrumented = 0;
1237   total_num_blocks_created = 0;
1238   total_num_passes = 0;
1239   total_num_times_called = 0;
1240   total_num_branches = 0;
1241   total_num_never_executed = 0;
1242   for (i = 0; i < 20; i++)
1243     total_hist_br_prob[i] = 0;
1244 }
1245
1246 /* Performs file-level cleanup after branch-prob processing
1247    is completed.  */
1248
1249 void
1250 end_branch_prob ()
1251 {
1252   if (flag_test_coverage)
1253     {
1254       fclose (bb_file);
1255       fclose (bbg_file);
1256       unlink (da_file_name);
1257     }
1258
1259   if (flag_branch_probabilities && da_file)
1260     fclose (da_file);
1261
1262   if (rtl_dump_file)
1263     {
1264       fprintf (rtl_dump_file, "\n");
1265       fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1266                total_num_blocks);
1267       fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1268       fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1269                total_num_edges_ignored);
1270       fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1271                total_num_edges_instrumented);
1272       fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1273                total_num_blocks_created);
1274       fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1275                total_num_passes);
1276       if (total_num_times_called != 0)
1277         fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1278                  (total_num_passes + (total_num_times_called  >> 1))
1279                  / total_num_times_called);
1280       fprintf (rtl_dump_file, "Total number of branches: %d\n",
1281                total_num_branches);
1282       fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1283                total_num_never_executed);
1284       if (total_num_branches)
1285         {
1286           int i;
1287
1288           for (i = 0; i < 10; i++)
1289             fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1290                      (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1291                      / total_num_branches, 5*i, 5*i+5);
1292         }
1293     }
1294 }
1295 \f
1296 /* The label used by the edge profiling code.  */
1297
1298 static GTY(()) rtx profiler_label;
1299
1300 /* Initialize the profiler_label.  */
1301
1302 static void
1303 init_edge_profiler ()
1304 {
1305   /* Generate and save a copy of this so it can be shared.  */
1306   char buf[20];
1307   ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1308   profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1309 }
1310
1311 /* Output instructions as RTL to increment the edge execution count.  */
1312
1313 static rtx
1314 gen_edge_profiler (edgeno)
1315      int edgeno;
1316 {
1317   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1318   rtx mem_ref, tmp;
1319   rtx sequence;
1320
1321   start_sequence ();
1322
1323   tmp = force_reg (Pmode, profiler_label);
1324   tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1325   mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1326
1327   set_mem_alias_set (mem_ref, new_alias_set ());
1328
1329   tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1330                              mem_ref, 0, OPTAB_WIDEN);
1331
1332   if (tmp != mem_ref)
1333     emit_move_insn (copy_rtx (mem_ref), tmp);
1334
1335   sequence = get_insns ();
1336   end_sequence ();
1337   return sequence;
1338 }
1339
1340 /* Output code for a constructor that will invoke __bb_init_func, if
1341    this has not already been done.  */
1342
1343 void
1344 output_func_start_profiler ()
1345 {
1346   tree fnname, fndecl;
1347   char *name;
1348   char buf[20];
1349   const char *cfnname;
1350   rtx table_address;
1351   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1352   int save_flag_inline_functions = flag_inline_functions;
1353
1354   /* It's either already been output, or we don't need it because we're
1355      not doing profile-edges.  */
1356   if (! need_func_profiler)
1357     return;
1358
1359   need_func_profiler = 0;
1360
1361   /* Synthesize a constructor function to invoke __bb_init_func with a
1362      pointer to this object file's profile block.  */
1363
1364   /* Try and make a unique name given the "file function name".
1365
1366      And no, I don't like this either.  */
1367
1368   fnname = get_file_function_name ('I');
1369   cfnname = IDENTIFIER_POINTER (fnname);
1370   name = concat (cfnname, "GCOV", NULL);
1371   fnname = get_identifier (name);
1372   free (name);
1373
1374   fndecl = build_decl (FUNCTION_DECL, fnname,
1375                        build_function_type (void_type_node, NULL_TREE));
1376   DECL_EXTERNAL (fndecl) = 0;
1377
1378   /* It can be a static function as long as collect2 does not have
1379      to scan the object file to find its ctor/dtor routine.  */
1380   TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
1381
1382   TREE_USED (fndecl) = 1;
1383
1384   DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1385
1386   fndecl = (*lang_hooks.decls.pushdecl) (fndecl);
1387   rest_of_decl_compilation (fndecl, 0, 1, 0);
1388   announce_function (fndecl);
1389   current_function_decl = fndecl;
1390   DECL_INITIAL (fndecl) = error_mark_node;
1391   make_decl_rtl (fndecl, NULL);
1392   init_function_start (fndecl, input_filename, lineno);
1393   (*lang_hooks.decls.pushlevel) (0);
1394   expand_function_start (fndecl, 0);
1395   cfun->arc_profile = 0;
1396
1397   /* Actually generate the code to call __bb_init_func.  */
1398   ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
1399   table_address = force_reg (Pmode,
1400                              gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
1401   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_init_func"), LCT_NORMAL,
1402                      mode, 1, table_address, Pmode);
1403
1404   expand_function_end (input_filename, lineno, 0);
1405   (*lang_hooks.decls.poplevel) (1, 0, 1);
1406
1407   /* Since fndecl isn't in the list of globals, it would never be emitted
1408      when it's considered to be 'safe' for inlining, so turn off
1409      flag_inline_functions.  */
1410   flag_inline_functions = 0;
1411
1412   rest_of_compilation (fndecl);
1413
1414   /* Reset flag_inline_functions to its original value.  */
1415   flag_inline_functions = save_flag_inline_functions;
1416
1417   if (! quiet_flag)
1418     fflush (asm_out_file);
1419   current_function_decl = NULL_TREE;
1420
1421   if (targetm.have_ctors_dtors)
1422     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
1423                                      DEFAULT_INIT_PRIORITY);
1424 }
1425
1426 #include "gt-profile.h"