xref: /dragonfly/contrib/gcc-4.7/gcc/rtl.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1 /* RTL utility routines.
2    Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
3    2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4    Free Software Foundation, Inc.
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 /* This file is compiled twice: once for the generator programs
23    once for the compiler.  */
24 #ifdef GENERATOR_FILE
25 #include "bconfig.h"
26 #else
27 #include "config.h"
28 #endif
29 
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "ggc.h"
35 #ifdef GENERATOR_FILE
36 # include "errors.h"
37 #else
38 # include "diagnostic-core.h"
39 #endif
40 
41 
42 /* Indexed by rtx code, gives number of operands for an rtx with that code.
43    Does NOT include rtx header data (code and links).  */
44 
45 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   sizeof FORMAT - 1 ,
46 
47 const unsigned char rtx_length[NUM_RTX_CODE] = {
48 #include "rtl.def"
49 };
50 
51 #undef DEF_RTL_EXPR
52 
53 /* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
54 
55 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
56 
57 const char * const rtx_name[NUM_RTX_CODE] = {
58 #include "rtl.def"            /* rtl expressions are documented here */
59 };
60 
61 #undef DEF_RTL_EXPR
62 
63 /* Indexed by rtx code, gives a sequence of operand-types for
64    rtx's of that code.  The sequence is a C string in which
65    each character describes one operand.  */
66 
67 const char * const rtx_format[NUM_RTX_CODE] = {
68   /* "*" undefined.
69          can cause a warning message
70      "0" field is unused (or used in a phase-dependent manner)
71          prints nothing
72      "i" an integer
73          prints the integer
74      "n" like "i", but prints entries from `note_insn_name'
75      "w" an integer of width HOST_BITS_PER_WIDE_INT
76          prints the integer
77      "s" a pointer to a string
78          prints the string
79      "S" like "s", but optional:
80            the containing rtx may end before this operand
81      "T" like "s", but treated specially by the RTL reader;
82          only found in machine description patterns.
83      "e" a pointer to an rtl expression
84          prints the expression
85      "E" a pointer to a vector that points to a number of rtl expressions
86          prints a list of the rtl expressions
87      "V" like "E", but optional:
88            the containing rtx may end before this operand
89      "u" a pointer to another insn
90          prints the uid of the insn.
91      "b" is a pointer to a bitmap header.
92      "B" is a basic block pointer.
93      "t" is a tree pointer.  */
94 
95 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
96 #include "rtl.def"            /* rtl expressions are defined here */
97 #undef DEF_RTL_EXPR
98 };
99 
100 /* Indexed by rtx code, gives a character representing the "class" of
101    that rtx code.  See rtl.def for documentation on the defined classes.  */
102 
103 const enum rtx_class rtx_class[NUM_RTX_CODE] = {
104 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   CLASS,
105 #include "rtl.def"            /* rtl expressions are defined here */
106 #undef DEF_RTL_EXPR
107 };
108 
109 /* Indexed by rtx code, gives the size of the rtx in bytes.  */
110 
111 const unsigned char rtx_code_size[NUM_RTX_CODE] = {
112 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)                                 \
113   ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE || (ENUM) == CONST_FIXED\
114    ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT)      \
115    : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
116 
117 #include "rtl.def"
118 #undef DEF_RTL_EXPR
119 };
120 
121 /* Names for kinds of NOTEs and REG_NOTEs.  */
122 
123 const char * const note_insn_name[NOTE_INSN_MAX] =
124 {
125 #define DEF_INSN_NOTE(NAME) #NAME,
126 #include "insn-notes.def"
127 #undef DEF_INSN_NOTE
128 };
129 
130 const char * const reg_note_name[REG_NOTE_MAX] =
131 {
132 #define DEF_REG_NOTE(NAME) #NAME,
133 #include "reg-notes.def"
134 #undef DEF_REG_NOTE
135 };
136 
137 #ifdef GATHER_STATISTICS
138 static int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
139 static int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
140 static int rtvec_alloc_counts;
141 static int rtvec_alloc_sizes;
142 #endif
143 
144 
145 /* Allocate an rtx vector of N elements.
146    Store the length, and initialize all elements to zero.  */
147 
148 rtvec
rtvec_alloc(int n)149 rtvec_alloc (int n)
150 {
151   rtvec rt;
152 
153   rt = ggc_alloc_rtvec_sized (n);
154   /* Clear out the vector.  */
155   memset (&rt->elem[0], 0, n * sizeof (rtx));
156 
157   PUT_NUM_ELEM (rt, n);
158 
159 #ifdef GATHER_STATISTICS
160   rtvec_alloc_counts++;
161   rtvec_alloc_sizes += n * sizeof (rtx);
162 #endif
163 
164   return rt;
165 }
166 
167 /* Create a bitwise copy of VEC.  */
168 
169 rtvec
shallow_copy_rtvec(rtvec vec)170 shallow_copy_rtvec (rtvec vec)
171 {
172   rtvec newvec;
173   int n;
174 
175   n = GET_NUM_ELEM (vec);
176   newvec = rtvec_alloc (n);
177   memcpy (&newvec->elem[0], &vec->elem[0], sizeof (rtx) * n);
178   return newvec;
179 }
180 
181 /* Return the number of bytes occupied by rtx value X.  */
182 
183 unsigned int
rtx_size(const_rtx x)184 rtx_size (const_rtx x)
185 {
186   if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
187     return RTX_HDR_SIZE + sizeof (struct block_symbol);
188   return RTX_CODE_SIZE (GET_CODE (x));
189 }
190 
191 /* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
192    all the rest is initialized to zero.  */
193 
194 rtx
rtx_alloc_stat(RTX_CODE code MEM_STAT_DECL)195 rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
196 {
197   rtx rt = ggc_alloc_zone_rtx_def_stat (&rtl_zone, RTX_CODE_SIZE (code)
198                                         PASS_MEM_STAT);
199 
200   /* We want to clear everything up to the FLD array.  Normally, this
201      is one int, but we don't want to assume that and it isn't very
202      portable anyway; this is.  */
203 
204   memset (rt, 0, RTX_HDR_SIZE);
205   PUT_CODE (rt, code);
206 
207 #ifdef GATHER_STATISTICS
208   rtx_alloc_counts[code]++;
209   rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
210 #endif
211 
212   return rt;
213 }
214 
215 
216 /* Return true if ORIG is a sharable CONST.  */
217 
218 bool
shared_const_p(const_rtx orig)219 shared_const_p (const_rtx orig)
220 {
221   gcc_assert (GET_CODE (orig) == CONST);
222 
223   /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
224      a LABEL_REF, it isn't sharable.  */
225   return (GET_CODE (XEXP (orig, 0)) == PLUS
226             && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
227             && CONST_INT_P(XEXP (XEXP (orig, 0), 1)));
228 }
229 
230 
231 /* Create a new copy of an rtx.
232    Recursively copies the operands of the rtx,
233    except for those few rtx codes that are sharable.  */
234 
235 rtx
copy_rtx(rtx orig)236 copy_rtx (rtx orig)
237 {
238   rtx copy;
239   int i, j;
240   RTX_CODE code;
241   const char *format_ptr;
242 
243   code = GET_CODE (orig);
244 
245   switch (code)
246     {
247     case REG:
248     case DEBUG_EXPR:
249     case VALUE:
250     case CONST_INT:
251     case CONST_DOUBLE:
252     case CONST_FIXED:
253     case CONST_VECTOR:
254     case SYMBOL_REF:
255     case CODE_LABEL:
256     case PC:
257     case CC0:
258     case RETURN:
259     case SIMPLE_RETURN:
260     case SCRATCH:
261       /* SCRATCH must be shared because they represent distinct values.  */
262       return orig;
263     case CLOBBER:
264       if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
265           return orig;
266       break;
267 
268     case CONST:
269       if (shared_const_p (orig))
270           return orig;
271       break;
272 
273       /* A MEM with a constant address is not sharable.  The problem is that
274            the constant address may need to be reloaded.  If the mem is shared,
275            then reloading one copy of this mem will cause all copies to appear
276            to have been reloaded.  */
277 
278     default:
279       break;
280     }
281 
282   /* Copy the various flags, fields, and other information.  We assume
283      that all fields need copying, and then clear the fields that should
284      not be copied.  That is the sensible default behavior, and forces
285      us to explicitly document why we are *not* copying a flag.  */
286   copy = shallow_copy_rtx (orig);
287 
288   /* We do not copy the USED flag, which is used as a mark bit during
289      walks over the RTL.  */
290   RTX_FLAG (copy, used) = 0;
291 
292   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
293 
294   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
295     switch (*format_ptr++)
296       {
297       case 'e':
298           if (XEXP (orig, i) != NULL)
299             XEXP (copy, i) = copy_rtx (XEXP (orig, i));
300           break;
301 
302       case 'E':
303       case 'V':
304           if (XVEC (orig, i) != NULL)
305             {
306               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
307               for (j = 0; j < XVECLEN (copy, i); j++)
308                 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
309             }
310           break;
311 
312       case 't':
313       case 'w':
314       case 'i':
315       case 's':
316       case 'S':
317       case 'T':
318       case 'u':
319       case 'B':
320       case '0':
321           /* These are left unchanged.  */
322           break;
323 
324       default:
325           gcc_unreachable ();
326       }
327   return copy;
328 }
329 
330 /* Create a new copy of an rtx.  Only copy just one level.  */
331 
332 rtx
shallow_copy_rtx_stat(const_rtx orig MEM_STAT_DECL)333 shallow_copy_rtx_stat (const_rtx orig MEM_STAT_DECL)
334 {
335   const unsigned int size = rtx_size (orig);
336   rtx const copy = ggc_alloc_zone_rtx_def_stat (&rtl_zone, size PASS_MEM_STAT);
337   return (rtx) memcpy (copy, orig, size);
338 }
339 
340 /* Nonzero when we are generating CONCATs.  */
341 int generating_concat_p;
342 
343 /* Nonzero when we are expanding trees to RTL.  */
344 int currently_expanding_to_rtl;
345 
346 
347 
348 /* Same as rtx_equal_p, but call CB on each pair of rtx if CB is not NULL.
349    When the callback returns true, we continue with the new pair.
350    Whenever changing this function check if rtx_equal_p below doesn't need
351    changing as well.  */
352 
353 int
rtx_equal_p_cb(const_rtx x,const_rtx y,rtx_equal_p_callback_function cb)354 rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
355 {
356   int i;
357   int j;
358   enum rtx_code code;
359   const char *fmt;
360   rtx nx, ny;
361 
362   if (x == y)
363     return 1;
364   if (x == 0 || y == 0)
365     return 0;
366 
367   /* Invoke the callback first.  */
368   if (cb != NULL
369       && ((*cb) (&x, &y, &nx, &ny)))
370     return rtx_equal_p_cb (nx, ny, cb);
371 
372   code = GET_CODE (x);
373   /* Rtx's of different codes cannot be equal.  */
374   if (code != GET_CODE (y))
375     return 0;
376 
377   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
378      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
379 
380   if (GET_MODE (x) != GET_MODE (y))
381     return 0;
382 
383   /* MEMs refering to different address space are not equivalent.  */
384   if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
385     return 0;
386 
387   /* Some RTL can be compared nonrecursively.  */
388   switch (code)
389     {
390     case REG:
391       return (REGNO (x) == REGNO (y));
392 
393     case LABEL_REF:
394       return XEXP (x, 0) == XEXP (y, 0);
395 
396     case SYMBOL_REF:
397       return XSTR (x, 0) == XSTR (y, 0);
398 
399     case DEBUG_EXPR:
400     case VALUE:
401     case SCRATCH:
402     case CONST_DOUBLE:
403     case CONST_INT:
404     case CONST_FIXED:
405       return 0;
406 
407     case DEBUG_IMPLICIT_PTR:
408       return DEBUG_IMPLICIT_PTR_DECL (x)
409                == DEBUG_IMPLICIT_PTR_DECL (y);
410 
411     case DEBUG_PARAMETER_REF:
412       return DEBUG_PARAMETER_REF_DECL (x)
413                == DEBUG_PARAMETER_REF_DECL (x);
414 
415     case ENTRY_VALUE:
416       return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
417 
418     default:
419       break;
420     }
421 
422   /* Compare the elements.  If any pair of corresponding elements
423      fail to match, return 0 for the whole thing.  */
424 
425   fmt = GET_RTX_FORMAT (code);
426   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
427     {
428       switch (fmt[i])
429           {
430           case 'w':
431             if (XWINT (x, i) != XWINT (y, i))
432               return 0;
433             break;
434 
435           case 'n':
436           case 'i':
437             if (XINT (x, i) != XINT (y, i))
438               {
439 #ifndef GENERATOR_FILE
440                 if (((code == ASM_OPERANDS && i == 6)
441                        || (code == ASM_INPUT && i == 1))
442                       && locator_eq (XINT (x, i), XINT (y, i)))
443                     break;
444 #endif
445                 return 0;
446               }
447             break;
448 
449           case 'V':
450           case 'E':
451             /* Two vectors must have the same length.  */
452             if (XVECLEN (x, i) != XVECLEN (y, i))
453               return 0;
454 
455             /* And the corresponding elements must match.  */
456             for (j = 0; j < XVECLEN (x, i); j++)
457               if (rtx_equal_p_cb (XVECEXP (x, i, j),
458                                 XVECEXP (y, i, j), cb) == 0)
459                 return 0;
460             break;
461 
462           case 'e':
463             if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0)
464               return 0;
465             break;
466 
467           case 'S':
468           case 's':
469             if ((XSTR (x, i) || XSTR (y, i))
470                 && (! XSTR (x, i) || ! XSTR (y, i)
471                       || strcmp (XSTR (x, i), XSTR (y, i))))
472               return 0;
473             break;
474 
475           case 'u':
476             /* These are just backpointers, so they don't matter.  */
477             break;
478 
479           case '0':
480           case 't':
481             break;
482 
483             /* It is believed that rtx's at this level will never
484                contain anything but integers and other rtx's,
485                except for within LABEL_REFs and SYMBOL_REFs.  */
486           default:
487             gcc_unreachable ();
488           }
489     }
490   return 1;
491 }
492 
493 /* Return 1 if X and Y are identical-looking rtx's.
494    This is the Lisp function EQUAL for rtx arguments.
495    Whenever changing this function check if rtx_equal_p_cb above doesn't need
496    changing as well.  */
497 
498 int
rtx_equal_p(const_rtx x,const_rtx y)499 rtx_equal_p (const_rtx x, const_rtx y)
500 {
501   int i;
502   int j;
503   enum rtx_code code;
504   const char *fmt;
505 
506   if (x == y)
507     return 1;
508   if (x == 0 || y == 0)
509     return 0;
510 
511   code = GET_CODE (x);
512   /* Rtx's of different codes cannot be equal.  */
513   if (code != GET_CODE (y))
514     return 0;
515 
516   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
517      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
518 
519   if (GET_MODE (x) != GET_MODE (y))
520     return 0;
521 
522   /* MEMs refering to different address space are not equivalent.  */
523   if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
524     return 0;
525 
526   /* Some RTL can be compared nonrecursively.  */
527   switch (code)
528     {
529     case REG:
530       return (REGNO (x) == REGNO (y));
531 
532     case LABEL_REF:
533       return XEXP (x, 0) == XEXP (y, 0);
534 
535     case SYMBOL_REF:
536       return XSTR (x, 0) == XSTR (y, 0);
537 
538     case DEBUG_EXPR:
539     case VALUE:
540     case SCRATCH:
541     case CONST_DOUBLE:
542     case CONST_INT:
543     case CONST_FIXED:
544       return 0;
545 
546     case DEBUG_IMPLICIT_PTR:
547       return DEBUG_IMPLICIT_PTR_DECL (x)
548                == DEBUG_IMPLICIT_PTR_DECL (y);
549 
550     case DEBUG_PARAMETER_REF:
551       return DEBUG_PARAMETER_REF_DECL (x)
552                == DEBUG_PARAMETER_REF_DECL (y);
553 
554     case ENTRY_VALUE:
555       return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
556 
557     default:
558       break;
559     }
560 
561   /* Compare the elements.  If any pair of corresponding elements
562      fail to match, return 0 for the whole thing.  */
563 
564   fmt = GET_RTX_FORMAT (code);
565   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
566     {
567       switch (fmt[i])
568           {
569           case 'w':
570             if (XWINT (x, i) != XWINT (y, i))
571               return 0;
572             break;
573 
574           case 'n':
575           case 'i':
576             if (XINT (x, i) != XINT (y, i))
577               {
578 #ifndef GENERATOR_FILE
579                 if (((code == ASM_OPERANDS && i == 6)
580                        || (code == ASM_INPUT && i == 1))
581                       && locator_eq (XINT (x, i), XINT (y, i)))
582                     break;
583 #endif
584                 return 0;
585               }
586             break;
587 
588           case 'V':
589           case 'E':
590             /* Two vectors must have the same length.  */
591             if (XVECLEN (x, i) != XVECLEN (y, i))
592               return 0;
593 
594             /* And the corresponding elements must match.  */
595             for (j = 0; j < XVECLEN (x, i); j++)
596               if (rtx_equal_p (XVECEXP (x, i, j),  XVECEXP (y, i, j)) == 0)
597                 return 0;
598             break;
599 
600           case 'e':
601             if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
602               return 0;
603             break;
604 
605           case 'S':
606           case 's':
607             if ((XSTR (x, i) || XSTR (y, i))
608                 && (! XSTR (x, i) || ! XSTR (y, i)
609                       || strcmp (XSTR (x, i), XSTR (y, i))))
610               return 0;
611             break;
612 
613           case 'u':
614             /* These are just backpointers, so they don't matter.  */
615             break;
616 
617           case '0':
618           case 't':
619             break;
620 
621             /* It is believed that rtx's at this level will never
622                contain anything but integers and other rtx's,
623                except for within LABEL_REFs and SYMBOL_REFs.  */
624           default:
625             gcc_unreachable ();
626           }
627     }
628   return 1;
629 }
630 
631 /* Iteratively hash rtx X.  */
632 
633 hashval_t
iterative_hash_rtx(const_rtx x,hashval_t hash)634 iterative_hash_rtx (const_rtx x, hashval_t hash)
635 {
636   enum rtx_code code;
637   enum machine_mode mode;
638   int i, j;
639   const char *fmt;
640 
641   if (x == NULL_RTX)
642     return hash;
643   code = GET_CODE (x);
644   hash = iterative_hash_object (code, hash);
645   mode = GET_MODE (x);
646   hash = iterative_hash_object (mode, hash);
647   switch (code)
648     {
649     case REG:
650       i = REGNO (x);
651       return iterative_hash_object (i, hash);
652     case CONST_INT:
653       return iterative_hash_object (INTVAL (x), hash);
654     case SYMBOL_REF:
655       if (XSTR (x, 0))
656           return iterative_hash (XSTR (x, 0), strlen (XSTR (x, 0)) + 1,
657                                      hash);
658       return hash;
659     case LABEL_REF:
660     case DEBUG_EXPR:
661     case VALUE:
662     case SCRATCH:
663     case CONST_DOUBLE:
664     case CONST_FIXED:
665     case DEBUG_IMPLICIT_PTR:
666     case DEBUG_PARAMETER_REF:
667       return hash;
668     default:
669       break;
670     }
671 
672   fmt = GET_RTX_FORMAT (code);
673   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
674     switch (fmt[i])
675       {
676       case 'w':
677           hash = iterative_hash_object (XWINT (x, i), hash);
678           break;
679       case 'n':
680       case 'i':
681           hash = iterative_hash_object (XINT (x, i), hash);
682           break;
683       case 'V':
684       case 'E':
685           j = XVECLEN (x, i);
686           hash = iterative_hash_object (j, hash);
687           for (j = 0; j < XVECLEN (x, i); j++)
688             hash = iterative_hash_rtx (XVECEXP (x, i, j), hash);
689           break;
690       case 'e':
691           hash = iterative_hash_rtx (XEXP (x, i), hash);
692           break;
693       case 'S':
694       case 's':
695           if (XSTR (x, i))
696             hash = iterative_hash (XSTR (x, 0), strlen (XSTR (x, 0)) + 1,
697                                          hash);
698           break;
699       default:
700           break;
701       }
702   return hash;
703 }
704 
705 void
dump_rtx_statistics(void)706 dump_rtx_statistics (void)
707 {
708 #ifdef GATHER_STATISTICS
709   int i;
710   int total_counts = 0;
711   int total_sizes = 0;
712   fprintf (stderr, "\nRTX Kind               Count      Bytes\n");
713   fprintf (stderr, "---------------------------------------\n");
714   for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
715     if (rtx_alloc_counts[i])
716       {
717         fprintf (stderr, "%-20s %7d %10d\n", GET_RTX_NAME (i),
718                  rtx_alloc_counts[i], rtx_alloc_sizes[i]);
719         total_counts += rtx_alloc_counts[i];
720         total_sizes += rtx_alloc_sizes[i];
721       }
722   if (rtvec_alloc_counts)
723     {
724       fprintf (stderr, "%-20s %7d %10d\n", "rtvec",
725                rtvec_alloc_counts, rtvec_alloc_sizes);
726       total_counts += rtvec_alloc_counts;
727       total_sizes += rtvec_alloc_sizes;
728     }
729   fprintf (stderr, "---------------------------------------\n");
730   fprintf (stderr, "%-20s %7d %10d\n",
731            "Total", total_counts, total_sizes);
732   fprintf (stderr, "---------------------------------------\n");
733 #endif
734 }
735 
736 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
737 void
rtl_check_failed_bounds(const_rtx r,int n,const char * file,int line,const char * func)738 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line,
739                                const char *func)
740 {
741   internal_error
742     ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
743      n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
744      func, trim_filename (file), line);
745 }
746 
747 void
rtl_check_failed_type1(const_rtx r,int n,int c1,const char * file,int line,const char * func)748 rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line,
749                               const char *func)
750 {
751   internal_error
752     ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
753      n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
754      func, trim_filename (file), line);
755 }
756 
757 void
rtl_check_failed_type2(const_rtx r,int n,int c1,int c2,const char * file,int line,const char * func)758 rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file,
759                               int line, const char *func)
760 {
761   internal_error
762     ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
763      n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
764      func, trim_filename (file), line);
765 }
766 
767 void
rtl_check_failed_code1(const_rtx r,enum rtx_code code,const char * file,int line,const char * func)768 rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file,
769                               int line, const char *func)
770 {
771   internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
772                       GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
773                       trim_filename (file), line);
774 }
775 
776 void
rtl_check_failed_code2(const_rtx r,enum rtx_code code1,enum rtx_code code2,const char * file,int line,const char * func)777 rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
778                               const char *file, int line, const char *func)
779 {
780   internal_error
781     ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
782      GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
783      func, trim_filename (file), line);
784 }
785 
786 void
rtl_check_failed_code_mode(const_rtx r,enum rtx_code code,enum machine_mode mode,bool not_mode,const char * file,int line,const char * func)787 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, enum machine_mode mode,
788                                   bool not_mode, const char *file, int line,
789                                   const char *func)
790 {
791   internal_error ((not_mode
792                        ? ("RTL check: expected code '%s' and not mode '%s', "
793                           "have code '%s' and mode '%s' in %s, at %s:%d")
794                        : ("RTL check: expected code '%s' and mode '%s', "
795                           "have code '%s' and mode '%s' in %s, at %s:%d")),
796                       GET_RTX_NAME (code), GET_MODE_NAME (mode),
797                       GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
798                       func, trim_filename (file), line);
799 }
800 
801 /* Report that line LINE of FILE tried to access the block symbol fields
802    of a non-block symbol.  FUNC is the function that contains the line.  */
803 
804 void
rtl_check_failed_block_symbol(const char * file,int line,const char * func)805 rtl_check_failed_block_symbol (const char *file, int line, const char *func)
806 {
807   internal_error
808     ("RTL check: attempt to treat non-block symbol as a block symbol "
809      "in %s, at %s:%d", func, trim_filename (file), line);
810 }
811 
812 /* XXX Maybe print the vector?  */
813 void
rtvec_check_failed_bounds(const_rtvec r,int n,const char * file,int line,const char * func)814 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line,
815                                  const char *func)
816 {
817   internal_error
818     ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
819      n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
820 }
821 #endif /* ENABLE_RTL_CHECKING */
822 
823 #if defined ENABLE_RTL_FLAG_CHECKING
824 void
rtl_check_failed_flag(const char * name,const_rtx r,const char * file,int line,const char * func)825 rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
826                            int line, const char *func)
827 {
828   internal_error
829     ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
830      name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
831 }
832 #endif /* ENABLE_RTL_FLAG_CHECKING */
833