OSDN Git Service

* config/mips/t-elf (EXTRA_PARTS): Use EXTRA_MULTILIB_PARTS instead.
[pf3gnuchains/gcc-fork.git] / gcc / print-rtl.c
1 /* Print RTL for GNU C Compiler.
2    Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "real.h"
27 #include "flags.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30
31 /* How to print out a register name.
32    We don't use PRINT_REG because some definitions of PRINT_REG
33    don't work here.  */
34 #ifndef DEBUG_PRINT_REG
35 #define DEBUG_PRINT_REG(RTX, CODE, FILE) \
36   fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)])
37 #endif
38
39 /* Array containing all of the register names */
40
41 #ifdef DEBUG_REGISTER_NAMES
42 static const char * const debug_reg_names[] = DEBUG_REGISTER_NAMES;
43 #define reg_names debug_reg_names
44 #else
45 const char * reg_names[] = REGISTER_NAMES;
46 #endif
47
48 static FILE *outfile;
49
50 static int sawclose = 0;
51
52 static int indent;
53
54 static void print_rtx           PARAMS ((rtx));
55
56 /* String printed at beginning of each RTL when it is dumped.
57    This string is set to ASM_COMMENT_START when the RTL is dumped in
58    the assembly output file.  */
59 const char *print_rtx_head = "";
60
61 /* Nonzero means suppress output of instruction numbers and line number
62    notes in debugging dumps.
63    This must be defined here so that programs like gencodes can be linked.  */
64 int flag_dump_unnumbered = 0;
65
66 /* Nonzero means use simplified format without flags, modes, etc.  */
67 int flag_simple = 0;
68
69 /* Nonzero if we are dumping graphical description.  */
70 int dump_for_graph;
71
72 /* Nonzero to dump all call_placeholder alternatives.  */
73 static int debug_call_placeholder_verbose;
74
75 /* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
76
77 static void
78 print_rtx (in_rtx)
79      register rtx in_rtx;
80 {
81   register int i = 0;
82   register int j;
83   register const char *format_ptr;
84   register int is_insn;
85   rtx tem;
86
87   if (sawclose)
88     {
89       if (flag_simple)
90         fputc (' ', outfile);
91       else
92         fprintf (outfile, "\n%s%*s",
93                  print_rtx_head, indent * 2, "");
94       sawclose = 0;
95     }
96
97   if (in_rtx == 0)
98     {
99       fputs ("(nil)", outfile);
100       sawclose = 1;
101       return;
102     }
103
104   is_insn = (INSN_P (in_rtx));
105
106   /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
107      in separate nodes and therefore have to handle them special here.  */
108   if (dump_for_graph &&
109       (is_insn || GET_CODE (in_rtx) == NOTE || GET_CODE (in_rtx) == CODE_LABEL
110        || GET_CODE (in_rtx) == BARRIER))
111     {
112       i = 3;
113       indent = 0;
114     }
115   else
116     {
117       /* print name of expression code */
118       if (flag_simple && GET_CODE (in_rtx) == CONST_INT)
119         fputc ('(', outfile);
120       else
121         fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
122       
123       if (! flag_simple)
124         {
125           if (in_rtx->in_struct)
126             fputs ("/s", outfile);
127
128           if (in_rtx->volatil)
129             fputs ("/v", outfile);
130           
131           if (in_rtx->unchanging)
132             fputs ("/u", outfile);
133           
134           if (in_rtx->integrated)
135             fputs ("/i", outfile);
136           
137           if (in_rtx->frame_related)
138             fputs ("/f", outfile);
139           
140           if (in_rtx->jump)
141             fputs ("/j", outfile);
142           
143           if (in_rtx->call)
144             fputs ("/c", outfile);
145
146           if (GET_MODE (in_rtx) != VOIDmode)
147             {
148               /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
149               if (GET_CODE (in_rtx) == EXPR_LIST 
150                   || GET_CODE (in_rtx) == INSN_LIST)
151                 fprintf (outfile, ":%s",
152                          GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
153               else
154                 fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
155             }
156         }
157     }
158
159   /* Get the format string and skip the first elements if we have handled
160      them already.  */
161   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
162
163   for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
164     switch (*format_ptr++)
165       {
166         const char *str;
167
168       case 'T':
169         str = XTMPL (in_rtx, i);
170         goto string;
171
172       case 'S':
173       case 's':
174         str = XSTR (in_rtx, i);
175       string:
176
177         if (str == 0)
178           fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
179         else
180           {
181             if (dump_for_graph)
182               fprintf (outfile, " (\\\"%s\\\")", str);
183             else
184               fprintf (outfile, " (\"%s\")", str);
185           }
186         sawclose = 1;
187         break;
188
189         /* 0 indicates a field for internal use that should not be printed.
190            An exception is the third field of a NOTE, where it indicates
191            that the field has several different valid contents.  */
192       case '0':
193         if (i == 1 && GET_CODE (in_rtx) == REG)
194           {
195             if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
196               fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
197             break;
198           }
199         if (i == 3 && GET_CODE (in_rtx) == NOTE)
200           {
201             switch (NOTE_LINE_NUMBER (in_rtx))
202               {
203               case NOTE_INSN_EH_REGION_BEG:
204               case NOTE_INSN_EH_REGION_END:
205                 if (flag_dump_unnumbered)
206                   fprintf (outfile, " #");
207                 else
208                   fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
209                 sawclose = 1;
210                 break;
211
212               case NOTE_INSN_BLOCK_BEG:
213               case NOTE_INSN_BLOCK_END:
214                 fprintf (outfile, " ");
215                 if (flag_dump_unnumbered)
216                   fprintf (outfile, "#");
217                 else
218                   fprintf (outfile, HOST_PTR_PRINTF, 
219                            (char *) NOTE_BLOCK (in_rtx));
220                 sawclose = 1;
221                 break;
222
223               case NOTE_INSN_RANGE_BEG:
224               case NOTE_INSN_RANGE_END:
225               case NOTE_INSN_LIVE:
226                 indent += 2;
227                 if (!sawclose)
228                   fprintf (outfile, " ");
229                 print_rtx (NOTE_RANGE_INFO (in_rtx));
230                 indent -= 2;
231                 break;
232
233               case NOTE_INSN_BASIC_BLOCK:
234                 {
235                   basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
236                   if (bb != 0)
237                     fprintf (outfile, " [bb %d]", bb->index);
238                   break;
239                 }
240
241               case NOTE_INSN_EXPECTED_VALUE:
242                 indent += 2;
243                 if (!sawclose)
244                   fprintf (outfile, " ");
245                 print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
246                 indent -= 2;
247                 break;
248
249               case NOTE_INSN_DELETED_LABEL:
250                 if (NOTE_SOURCE_FILE (in_rtx))
251                   fprintf (outfile, " (\"%s\")", NOTE_SOURCE_FILE (in_rtx));
252                 else
253                   fprintf (outfile, " \"\"");
254                 break;
255
256               default:
257                 {
258                   const char * const str = X0STR (in_rtx, i);
259
260                   if (NOTE_LINE_NUMBER (in_rtx) < 0)
261                     ;
262                   else if (str == 0)
263                     fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
264                   else
265                     {
266                       if (dump_for_graph)
267                         fprintf (outfile, " (\\\"%s\\\")", str);
268                       else
269                         fprintf (outfile, " (\"%s\")", str);
270                     }
271                   break;
272                 }
273               }
274           }
275         break;
276
277       case 'e':
278       do_e:
279         indent += 2;
280         if (!sawclose)
281           fprintf (outfile, " ");
282         print_rtx (XEXP (in_rtx, i));
283         indent -= 2;
284         break;
285
286       case 'E':
287       case 'V':
288         indent += 2;
289         if (sawclose)
290           {
291             fprintf (outfile, "\n%s%*s",
292                      print_rtx_head, indent * 2, "");
293             sawclose = 0;
294           }
295         fputs ("[ ", outfile);
296         if (NULL != XVEC (in_rtx, i))
297           {
298             indent += 2;
299             if (XVECLEN (in_rtx, i))
300               sawclose = 1;
301
302             for (j = 0; j < XVECLEN (in_rtx, i); j++)
303               print_rtx (XVECEXP (in_rtx, i, j));
304
305             indent -= 2;
306           }
307         if (sawclose)
308           fprintf (outfile, "\n%s%*s",
309                    print_rtx_head, indent * 2, "");
310
311         fputs ("] ", outfile);
312         sawclose = 1;
313         indent -= 2;
314         break;
315
316       case 'w':
317         if (! flag_simple)
318           fprintf (outfile, " ");
319         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
320         if (! flag_simple)
321           {
322             fprintf (outfile, " [");
323             fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, XWINT (in_rtx, i));
324             fprintf (outfile, "]");
325           }
326         break;
327
328       case 'i':
329         if (i == 5 && GET_CODE (in_rtx) == NOTE)
330           {
331             /* This field is only used for NOTE_INSN_DELETED_LABEL, and
332                other times often contains garbage from INSN->NOTE death.  */
333             if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_DELETED_LABEL)
334               fprintf (outfile, " %d",  XINT (in_rtx, i));
335           }
336         else
337           {
338             register int value = XINT (in_rtx, i);
339             const char *name;
340
341             if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
342               {
343                 fputc (' ', outfile);
344                 DEBUG_PRINT_REG (in_rtx, 0, outfile);
345               }
346             else if (GET_CODE (in_rtx) == REG
347                      && value <= LAST_VIRTUAL_REGISTER)
348               {
349                 if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
350                   fprintf (outfile, " %d virtual-incoming-args", value);
351                 else if (value == VIRTUAL_STACK_VARS_REGNUM)
352                   fprintf (outfile, " %d virtual-stack-vars", value);
353                 else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
354                   fprintf (outfile, " %d virtual-stack-dynamic", value);
355                 else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
356                   fprintf (outfile, " %d virtual-outgoing-args", value);
357                 else if (value == VIRTUAL_CFA_REGNUM)
358                   fprintf (outfile, " %d virtual-cfa", value);
359                 else
360                   fprintf (outfile, " %d virtual-reg-%d", value,
361                            value-FIRST_VIRTUAL_REGISTER);
362               }
363             else if (flag_dump_unnumbered
364                      && (is_insn || GET_CODE (in_rtx) == NOTE))
365               fputc ('#', outfile);
366             else
367               fprintf (outfile, " %d", value);
368
369             if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
370                 && XINT (in_rtx, i) >= 0
371                 && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
372               fprintf (outfile, " {%s}", name);
373             sawclose = 0;
374           }
375         break;
376
377       /* Print NOTE_INSN names rather than integer codes.  */
378
379       case 'n':
380         if (XINT (in_rtx, i) >= (int) NOTE_INSN_BIAS
381             && XINT (in_rtx, i) < (int) NOTE_INSN_MAX)
382           fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
383         else
384           fprintf (outfile, " %d", XINT (in_rtx, i));
385         sawclose = 0;
386         break;
387
388       case 'u':
389         if (XEXP (in_rtx, i) != NULL)
390           {
391             rtx sub = XEXP (in_rtx, i);
392             enum rtx_code subc = GET_CODE (sub);
393
394             if (GET_CODE (in_rtx) == LABEL_REF)
395               {
396                 if (subc == NOTE
397                     && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
398                   {
399                     if (flag_dump_unnumbered)
400                       fprintf (outfile, " [# deleted]");
401                     else
402                       fprintf (outfile, " [%d deleted]", INSN_UID (sub));
403                     sawclose = 0;
404                     break;
405                   }
406
407                 if (subc != CODE_LABEL)
408                   goto do_e;
409               }
410
411             if (flag_dump_unnumbered)
412               fputs (" #", outfile);
413             else
414               fprintf (outfile, " %d", INSN_UID (sub));
415           }
416         else
417           fputs (" 0", outfile);
418         sawclose = 0;
419         break;
420
421       case 'b':
422         if (XBITMAP (in_rtx, i) == NULL)
423           fputs (" {null}", outfile);
424         else
425           bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
426         sawclose = 0;
427         break;
428
429       case 't':
430         putc (' ', outfile);
431         fprintf (outfile, HOST_PTR_PRINTF, (char *) XTREE (in_rtx, i));
432         break;
433
434       case '*':
435         fputs (" Unknown", outfile);
436         sawclose = 0;
437         break;
438
439       default:
440         fprintf (stderr,
441                  "switch format wrong in rtl.print_rtx(). format was: %c.\n",
442                  format_ptr[-1]);
443         abort ();
444       }
445
446   switch (GET_CODE (in_rtx))
447     {
448     case MEM:
449       fputc (' ', outfile);
450       fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
451       break;
452
453 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && MAX_LONG_DOUBLE_TYPE_SIZE == 64
454     case CONST_DOUBLE:
455       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
456         {
457           double val;
458           REAL_VALUE_FROM_CONST_DOUBLE (val, in_rtx);
459           fprintf (outfile, " [%.16g]", val);
460         }
461       break;
462 #endif
463
464     case CODE_LABEL:
465       fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
466       if (LABEL_ALTERNATE_NAME (in_rtx))
467         fprintf (outfile, " [alternate name: %s]",
468                  LABEL_ALTERNATE_NAME (in_rtx));
469       break;
470
471     case CALL_PLACEHOLDER:
472       if (debug_call_placeholder_verbose)
473         {
474           fputs (" (cond [\n  (const_string \"normal\") (sequence [", outfile);
475           for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
476             {
477               fputs ("\n    ", outfile);
478               print_inline_rtx (outfile, tem, 4);
479             }
480
481           tem = XEXP (in_rtx, 1);
482           if (tem)
483             fputs ("\n    ])\n  (const_string \"tail_call\") (sequence [", outfile);
484           for (; tem != 0; tem = NEXT_INSN (tem))
485             {
486               fputs ("\n    ", outfile);
487               print_inline_rtx (outfile, tem, 4);
488             }
489
490           tem = XEXP (in_rtx, 2);
491           if (tem)
492             fputs ("\n    ])\n  (const_string \"tail_recursion\") (sequence [", outfile);
493           for (; tem != 0; tem = NEXT_INSN (tem))
494             {
495               fputs ("\n    ", outfile);
496               print_inline_rtx (outfile, tem, 4);
497             }
498
499           fputs ("\n    ])\n  ])", outfile);
500           break;
501         }
502
503       for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
504         if (GET_CODE (tem) == CALL_INSN)
505           {
506             fprintf (outfile, " ");
507             print_rtx (tem);
508             break;
509           }
510       break;
511
512     default:
513       break;
514     }
515
516   if (dump_for_graph
517       && (is_insn || GET_CODE (in_rtx) == NOTE
518           || GET_CODE (in_rtx) == CODE_LABEL || GET_CODE (in_rtx) == BARRIER))
519     sawclose = 0;
520   else
521     {
522       fputc (')', outfile);
523       sawclose = 1;
524     }
525 }
526
527 /* Print an rtx on the current line of FILE.  Initially indent IND
528    characters.  */
529
530 void
531 print_inline_rtx (outf, x, ind)
532      FILE *outf;
533      rtx x;
534      int ind;
535 {
536   int oldsaw = sawclose;
537   int oldindent = indent;
538
539   sawclose = 0;
540   indent = ind;
541   outfile = outf;
542   print_rtx (x);
543   sawclose = oldsaw;
544   indent = oldindent;
545 }
546
547 /* Call this function from the debugger to see what X looks like.  */
548
549 void
550 debug_rtx (x)
551      rtx x;
552 {
553   outfile = stderr;
554   print_rtx (x);
555   fprintf (stderr, "\n");
556 }
557
558 /* Count of rtx's to print with debug_rtx_list.
559    This global exists because gdb user defined commands have no arguments.  */
560
561 int debug_rtx_count = 0;        /* 0 is treated as equivalent to 1 */
562
563 /* Call this function to print list from X on.
564
565    N is a count of the rtx's to print. Positive values print from the specified
566    rtx on.  Negative values print a window around the rtx.
567    EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
568
569 void
570 debug_rtx_list (x, n)
571      rtx x;
572      int n;
573 {
574   int i,count;
575   rtx insn;
576
577   count = n == 0 ? 1 : n < 0 ? -n : n;
578
579   /* If we are printing a window, back up to the start.  */
580
581   if (n < 0)
582     for (i = count / 2; i > 0; i--)
583       {
584         if (PREV_INSN (x) == 0)
585           break;
586         x = PREV_INSN (x);
587       }
588
589   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
590     debug_rtx (insn);
591 }
592
593 /* Call this function to print an rtx list from START to END inclusive.  */
594
595 void
596 debug_rtx_range (start, end)
597      rtx start, end;
598 {
599   while (1)
600     {
601       debug_rtx (start);
602       if (!start || start == end)
603         break;
604       start = NEXT_INSN (start);
605     }
606 }
607
608 /* Call this function to search an rtx list to find one with insn uid UID,
609    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
610    The found insn is returned to enable further debugging analysis.  */
611
612 rtx
613 debug_rtx_find (x, uid)
614      rtx x;
615      int uid;
616 {
617   while (x != 0 && INSN_UID (x) != uid)
618     x = NEXT_INSN (x);
619   if (x != 0)
620     {
621       debug_rtx_list (x, debug_rtx_count);
622       return x;
623     }
624   else
625     {
626       fprintf (stderr, "insn uid %d not found\n", uid);
627       return 0;
628     }
629 }
630
631 /* External entry point for printing a chain of insns
632    starting with RTX_FIRST onto file OUTF.
633    A blank line separates insns.
634
635    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
636
637 void
638 print_rtl (outf, rtx_first)
639      FILE *outf;
640      rtx rtx_first;
641 {
642   register rtx tmp_rtx;
643
644   outfile = outf;
645   sawclose = 0;
646
647   if (rtx_first == 0)
648     {
649       fputs (print_rtx_head, outf);
650       fputs ("(nil)\n", outf);
651     }
652   else
653     switch (GET_CODE (rtx_first))
654       {
655       case INSN:
656       case JUMP_INSN:
657       case CALL_INSN:
658       case NOTE:
659       case CODE_LABEL:
660       case BARRIER:
661         for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
662           if (! flag_dump_unnumbered
663               || GET_CODE (tmp_rtx) != NOTE || NOTE_LINE_NUMBER (tmp_rtx) < 0)
664             {
665               fputs (print_rtx_head, outfile);
666               print_rtx (tmp_rtx);
667               fprintf (outfile, "\n");
668             }
669         break;
670
671       default:
672         fputs (print_rtx_head, outfile);
673         print_rtx (rtx_first);
674       }
675 }
676
677 /* Like print_rtx, except specify a file.  */
678 /* Return nonzero if we actually printed anything.  */
679
680 int
681 print_rtl_single (outf, x)
682      FILE *outf;
683      rtx x;
684 {
685   outfile = outf;
686   sawclose = 0;
687   if (! flag_dump_unnumbered
688       || GET_CODE (x) != NOTE || NOTE_LINE_NUMBER (x) < 0)
689     {
690       fputs (print_rtx_head, outfile);
691       print_rtx (x);
692       putc ('\n', outf);
693       return 1;
694     }
695   return 0;
696 }
697
698
699 /* Like print_rtl except without all the detail; for example,
700    if RTX is a CONST_INT then print in decimal format.  */
701
702 void
703 print_simple_rtl (outf, x)
704      FILE *outf;
705      rtx x;
706 {
707   flag_simple = 1;
708   print_rtl (outf, x);
709   flag_simple = 0;
710 }