xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/rtl.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1 /* RTL utility routines.
2    Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 /* This file is compiled twice: once for the generator programs
21    once for the compiler.  */
22 #ifdef GENERATOR_FILE
23 #include "bconfig.h"
24 #else
25 #include "config.h"
26 #endif
27 
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "rtl.h"
32 #ifdef GENERATOR_FILE
33 # include "errors.h"
34 #else
35 # include "rtlhash.h"
36 # include "diagnostic-core.h"
37 #endif
38 
39 
40 /* Indexed by rtx code, gives number of operands for an rtx with that code.
41    Does NOT include rtx header data (code and links).  */
42 
43 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   sizeof FORMAT - 1 ,
44 
45 const unsigned char rtx_length[NUM_RTX_CODE] = {
46 #include "rtl.def"
47 };
48 
49 #undef DEF_RTL_EXPR
50 
51 /* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
52 
53 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
54 
55 const char * const rtx_name[NUM_RTX_CODE] = {
56 #include "rtl.def"		/* rtl expressions are documented here */
57 };
58 
59 #undef DEF_RTL_EXPR
60 
61 /* Indexed by rtx code, gives a sequence of operand-types for
62    rtx's of that code.  The sequence is a C string in which
63    each character describes one operand.  */
64 
65 const char * const rtx_format[NUM_RTX_CODE] = {
66   /* "*" undefined.
67          can cause a warning message
68      "0" field is unused (or used in a phase-dependent manner)
69          prints nothing
70      "i" an integer
71          prints the integer
72      "n" like "i", but prints entries from `note_insn_name'
73      "w" an integer of width HOST_BITS_PER_WIDE_INT
74          prints the integer
75      "s" a pointer to a string
76          prints the string
77      "S" like "s", but optional:
78 	 the containing rtx may end before this operand
79      "T" like "s", but treated specially by the RTL reader;
80          only found in machine description patterns.
81      "e" a pointer to an rtl expression
82          prints the expression
83      "E" a pointer to a vector that points to a number of rtl expressions
84          prints a list of the rtl expressions
85      "V" like "E", but optional:
86 	 the containing rtx may end before this operand
87      "u" a pointer to another insn
88          prints the uid of the insn.
89      "b" is a pointer to a bitmap header.
90      "B" is a basic block pointer.
91      "t" is a tree pointer.
92      "r" a register.
93      "p" is a poly_uint16 offset.  */
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 /* Whether rtxs with the given code store data in the hwint field.  */
110 
111 #define RTX_CODE_HWINT_P_1(ENUM)					\
112     ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE			\
113      || (ENUM) == CONST_FIXED || (ENUM) == CONST_WIDE_INT)
114 #ifdef GENERATOR_FILE
115 #define RTX_CODE_HWINT_P(ENUM)						\
116     (RTX_CODE_HWINT_P_1 (ENUM) || (ENUM) == EQ_ATTR_ALT)
117 #else
118 #define RTX_CODE_HWINT_P RTX_CODE_HWINT_P_1
119 #endif
120 
121 /* Indexed by rtx code, gives the size of the rtx in bytes.  */
122 
123 const unsigned char rtx_code_size[NUM_RTX_CODE] = {
124 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)				\
125   (RTX_CODE_HWINT_P (ENUM)						\
126    ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT)	\
127    : (ENUM) == REG							\
128    ? RTX_HDR_SIZE + sizeof (reg_info)					\
129    : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
130 
131 #include "rtl.def"
132 #undef DEF_RTL_EXPR
133 };
134 
135 /* Names for kinds of NOTEs and REG_NOTEs.  */
136 
137 const char * const note_insn_name[NOTE_INSN_MAX] =
138 {
139 #define DEF_INSN_NOTE(NAME) #NAME,
140 #include "insn-notes.def"
141 #undef DEF_INSN_NOTE
142 };
143 
144 const char * const reg_note_name[REG_NOTE_MAX] =
145 {
146 #define DEF_REG_NOTE(NAME) #NAME,
147 #include "reg-notes.def"
148 #undef DEF_REG_NOTE
149 };
150 
151 static size_t rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
152 static size_t rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
153 static size_t rtvec_alloc_counts;
154 static size_t rtvec_alloc_sizes;
155 
156 
157 /* Allocate an rtx vector of N elements.
158    Store the length, and initialize all elements to zero.  */
159 
160 rtvec
rtvec_alloc(int n)161 rtvec_alloc (int n)
162 {
163   rtvec rt;
164 
165   rt = ggc_alloc_rtvec_sized (n);
166   /* Clear out the vector.  */
167   memset (&rt->elem[0], 0, n * sizeof (rtx));
168 
169   PUT_NUM_ELEM (rt, n);
170 
171   if (GATHER_STATISTICS)
172     {
173       rtvec_alloc_counts++;
174       rtvec_alloc_sizes += n * sizeof (rtx);
175     }
176 
177   return rt;
178 }
179 
180 /* Create a bitwise copy of VEC.  */
181 
182 rtvec
shallow_copy_rtvec(rtvec vec)183 shallow_copy_rtvec (rtvec vec)
184 {
185   rtvec newvec;
186   int n;
187 
188   n = GET_NUM_ELEM (vec);
189   newvec = rtvec_alloc (n);
190   memcpy (&newvec->elem[0], &vec->elem[0], sizeof (rtx) * n);
191   return newvec;
192 }
193 
194 /* Return the number of bytes occupied by rtx value X.  */
195 
196 unsigned int
rtx_size(const_rtx x)197 rtx_size (const_rtx x)
198 {
199   if (CONST_WIDE_INT_P (x))
200     return (RTX_HDR_SIZE
201 	    + sizeof (struct hwivec_def)
202 	    + ((CONST_WIDE_INT_NUNITS (x) - 1)
203 	       * sizeof (HOST_WIDE_INT)));
204   if (CONST_POLY_INT_P (x))
205     return (RTX_HDR_SIZE
206 	    + sizeof (struct const_poly_int_def)
207 	    + CONST_POLY_INT_COEFFS (x).extra_size ());
208   if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
209     return RTX_HDR_SIZE + sizeof (struct block_symbol);
210   return RTX_CODE_SIZE (GET_CODE (x));
211 }
212 
213 /* Allocate an rtx of code CODE with EXTRA bytes in it.  The CODE is
214    stored in the rtx; all the rest is initialized to zero.  */
215 
216 rtx
rtx_alloc_stat_v(RTX_CODE code MEM_STAT_DECL,int extra)217 rtx_alloc_stat_v (RTX_CODE code MEM_STAT_DECL, int extra)
218 {
219   rtx rt = ggc_alloc_rtx_def_stat (RTX_CODE_SIZE (code) + extra
220 				   PASS_MEM_STAT);
221 
222   rtx_init (rt, code);
223 
224   if (GATHER_STATISTICS)
225     {
226       rtx_alloc_counts[code]++;
227       rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
228     }
229 
230   return rt;
231 }
232 
233 /* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
234    all the rest is initialized to zero.  */
235 
236 rtx
rtx_alloc(RTX_CODE code MEM_STAT_DECL)237 rtx_alloc (RTX_CODE code MEM_STAT_DECL)
238 {
239   return rtx_alloc_stat_v (code PASS_MEM_STAT, 0);
240 }
241 
242 /* Write the wide constant X to OUTFILE.  */
243 
244 void
cwi_output_hex(FILE * outfile,const_rtx x)245 cwi_output_hex (FILE *outfile, const_rtx x)
246 {
247   int i = CWI_GET_NUM_ELEM (x);
248   gcc_assert (i > 0);
249   if (CWI_ELT (x, i - 1) == 0)
250     /* The HOST_WIDE_INT_PRINT_HEX prepends a 0x only if the val is
251        non zero.  We want all numbers to have a 0x prefix.  */
252     fprintf (outfile, "0x");
253   fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i));
254   while (--i >= 0)
255     fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i));
256 }
257 
258 
259 /* Return true if ORIG is a sharable CONST.  */
260 
261 bool
shared_const_p(const_rtx orig)262 shared_const_p (const_rtx orig)
263 {
264   gcc_assert (GET_CODE (orig) == CONST);
265 
266   /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
267      a LABEL_REF, it isn't sharable.  */
268   poly_int64 offset;
269   return (GET_CODE (XEXP (orig, 0)) == PLUS
270 	  && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
271 	  && poly_int_rtx_p (XEXP (XEXP (orig, 0), 1), &offset));
272 }
273 
274 
275 /* Create a new copy of an rtx.
276    Recursively copies the operands of the rtx,
277    except for those few rtx codes that are sharable.  */
278 
279 rtx
copy_rtx(rtx orig)280 copy_rtx (rtx orig)
281 {
282   rtx copy;
283   int i, j;
284   RTX_CODE code;
285   const char *format_ptr;
286 
287   code = GET_CODE (orig);
288 
289   switch (code)
290     {
291     case REG:
292     case DEBUG_EXPR:
293     case VALUE:
294     CASE_CONST_ANY:
295     case SYMBOL_REF:
296     case CODE_LABEL:
297     case PC:
298     case CC0:
299     case RETURN:
300     case SIMPLE_RETURN:
301     case SCRATCH:
302       /* SCRATCH must be shared because they represent distinct values.  */
303       return orig;
304     case CLOBBER:
305       /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
306          clobbers or clobbers of hard registers that originated as pseudos.
307          This is needed to allow safe register renaming.  */
308       if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER
309 	  && ORIGINAL_REGNO (XEXP (orig, 0)) == REGNO (XEXP (orig, 0)))
310 	return orig;
311       break;
312 
313     case CONST:
314       if (shared_const_p (orig))
315 	return orig;
316       break;
317 
318       /* A MEM with a constant address is not sharable.  The problem is that
319 	 the constant address may need to be reloaded.  If the mem is shared,
320 	 then reloading one copy of this mem will cause all copies to appear
321 	 to have been reloaded.  */
322 
323     default:
324       break;
325     }
326 
327   /* Copy the various flags, fields, and other information.  We assume
328      that all fields need copying, and then clear the fields that should
329      not be copied.  That is the sensible default behavior, and forces
330      us to explicitly document why we are *not* copying a flag.  */
331   copy = shallow_copy_rtx (orig);
332 
333   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
334 
335   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
336     switch (*format_ptr++)
337       {
338       case 'e':
339 	if (XEXP (orig, i) != NULL)
340 	  XEXP (copy, i) = copy_rtx (XEXP (orig, i));
341 	break;
342 
343       case 'E':
344       case 'V':
345 	if (XVEC (orig, i) != NULL)
346 	  {
347 	    XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
348 	    for (j = 0; j < XVECLEN (copy, i); j++)
349 	      XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
350 	  }
351 	break;
352 
353       case 't':
354       case 'w':
355       case 'i':
356       case 'p':
357       case 's':
358       case 'S':
359       case 'T':
360       case 'u':
361       case 'B':
362       case '0':
363 	/* These are left unchanged.  */
364 	break;
365 
366       default:
367 	gcc_unreachable ();
368       }
369   return copy;
370 }
371 
372 /* Create a new copy of an rtx.  Only copy just one level.  */
373 
374 rtx
shallow_copy_rtx(const_rtx orig MEM_STAT_DECL)375 shallow_copy_rtx (const_rtx orig MEM_STAT_DECL)
376 {
377   const unsigned int size = rtx_size (orig);
378   rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT);
379   memcpy (copy, orig, size);
380   switch (GET_CODE (orig))
381     {
382       /* RTX codes copy_rtx_if_shared_1 considers are shareable,
383 	 the used flag is often used for other purposes.  */
384     case REG:
385     case DEBUG_EXPR:
386     case VALUE:
387     CASE_CONST_ANY:
388     case SYMBOL_REF:
389     case CODE_LABEL:
390     case PC:
391     case CC0:
392     case RETURN:
393     case SIMPLE_RETURN:
394     case SCRATCH:
395       break;
396     default:
397       /* For all other RTXes clear the used flag on the copy.  */
398       RTX_FLAG (copy, used) = 0;
399       break;
400     }
401   return copy;
402 }
403 
404 /* Nonzero when we are generating CONCATs.  */
405 int generating_concat_p;
406 
407 /* Nonzero when we are expanding trees to RTL.  */
408 int currently_expanding_to_rtl;
409 
410 
411 
412 /* Same as rtx_equal_p, but call CB on each pair of rtx if CB is not NULL.
413    When the callback returns true, we continue with the new pair.
414    Whenever changing this function check if rtx_equal_p below doesn't need
415    changing as well.  */
416 
417 int
rtx_equal_p_cb(const_rtx x,const_rtx y,rtx_equal_p_callback_function cb)418 rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
419 {
420   int i;
421   int j;
422   enum rtx_code code;
423   const char *fmt;
424   rtx nx, ny;
425 
426   if (x == y)
427     return 1;
428   if (x == 0 || y == 0)
429     return 0;
430 
431   /* Invoke the callback first.  */
432   if (cb != NULL
433       && ((*cb) (&x, &y, &nx, &ny)))
434     return rtx_equal_p_cb (nx, ny, cb);
435 
436   code = GET_CODE (x);
437   /* Rtx's of different codes cannot be equal.  */
438   if (code != GET_CODE (y))
439     return 0;
440 
441   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
442      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
443 
444   if (GET_MODE (x) != GET_MODE (y))
445     return 0;
446 
447   /* MEMs referring to different address space are not equivalent.  */
448   if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
449     return 0;
450 
451   /* Some RTL can be compared nonrecursively.  */
452   switch (code)
453     {
454     case REG:
455       return (REGNO (x) == REGNO (y));
456 
457     case LABEL_REF:
458       return label_ref_label (x) == label_ref_label (y);
459 
460     case SYMBOL_REF:
461       return XSTR (x, 0) == XSTR (y, 0);
462 
463     case DEBUG_EXPR:
464     case VALUE:
465     case SCRATCH:
466     CASE_CONST_UNIQUE:
467       return 0;
468 
469     case CONST_VECTOR:
470       if (!same_vector_encodings_p (x, y))
471 	return false;
472       break;
473 
474     case DEBUG_IMPLICIT_PTR:
475       return DEBUG_IMPLICIT_PTR_DECL (x)
476 	     == DEBUG_IMPLICIT_PTR_DECL (y);
477 
478     case DEBUG_PARAMETER_REF:
479       return DEBUG_PARAMETER_REF_DECL (x)
480 	     == DEBUG_PARAMETER_REF_DECL (y);
481 
482     case ENTRY_VALUE:
483       return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
484 
485     default:
486       break;
487     }
488 
489   /* Compare the elements.  If any pair of corresponding elements
490      fail to match, return 0 for the whole thing.  */
491 
492   fmt = GET_RTX_FORMAT (code);
493   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
494     {
495       switch (fmt[i])
496 	{
497 	case 'w':
498 	  if (XWINT (x, i) != XWINT (y, i))
499 	    return 0;
500 	  break;
501 
502 	case 'n':
503 	case 'i':
504 	  if (XINT (x, i) != XINT (y, i))
505 	    {
506 #ifndef GENERATOR_FILE
507 	      if (((code == ASM_OPERANDS && i == 6)
508 		   || (code == ASM_INPUT && i == 1))
509 		  && XINT (x, i) == XINT (y, i))
510 		break;
511 #endif
512 	      return 0;
513 	    }
514 	  break;
515 
516 	case 'p':
517 	  if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
518 	    return 0;
519 	  break;
520 
521 	case 'V':
522 	case 'E':
523 	  /* Two vectors must have the same length.  */
524 	  if (XVECLEN (x, i) != XVECLEN (y, i))
525 	    return 0;
526 
527 	  /* And the corresponding elements must match.  */
528 	  for (j = 0; j < XVECLEN (x, i); j++)
529 	    if (rtx_equal_p_cb (XVECEXP (x, i, j),
530                                 XVECEXP (y, i, j), cb) == 0)
531 	      return 0;
532 	  break;
533 
534 	case 'e':
535 	  if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0)
536 	    return 0;
537 	  break;
538 
539 	case 'S':
540 	case 's':
541 	  if ((XSTR (x, i) || XSTR (y, i))
542 	      && (! XSTR (x, i) || ! XSTR (y, i)
543 		  || strcmp (XSTR (x, i), XSTR (y, i))))
544 	    return 0;
545 	  break;
546 
547 	case 'u':
548 	  /* These are just backpointers, so they don't matter.  */
549 	  break;
550 
551 	case '0':
552 	case 't':
553 	  break;
554 
555 	  /* It is believed that rtx's at this level will never
556 	     contain anything but integers and other rtx's,
557 	     except for within LABEL_REFs and SYMBOL_REFs.  */
558 	default:
559 	  gcc_unreachable ();
560 	}
561     }
562   return 1;
563 }
564 
565 /* Return 1 if X and Y are identical-looking rtx's.
566    This is the Lisp function EQUAL for rtx arguments.
567    Whenever changing this function check if rtx_equal_p_cb above doesn't need
568    changing as well.  */
569 
570 int
rtx_equal_p(const_rtx x,const_rtx y)571 rtx_equal_p (const_rtx x, const_rtx y)
572 {
573   int i;
574   int j;
575   enum rtx_code code;
576   const char *fmt;
577 
578   if (x == y)
579     return 1;
580   if (x == 0 || y == 0)
581     return 0;
582 
583   code = GET_CODE (x);
584   /* Rtx's of different codes cannot be equal.  */
585   if (code != GET_CODE (y))
586     return 0;
587 
588   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
589      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
590 
591   if (GET_MODE (x) != GET_MODE (y))
592     return 0;
593 
594   /* MEMs referring to different address space are not equivalent.  */
595   if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
596     return 0;
597 
598   /* Some RTL can be compared nonrecursively.  */
599   switch (code)
600     {
601     case REG:
602       return (REGNO (x) == REGNO (y));
603 
604     case LABEL_REF:
605       return label_ref_label (x) == label_ref_label (y);
606 
607     case SYMBOL_REF:
608       return XSTR (x, 0) == XSTR (y, 0);
609 
610     case DEBUG_EXPR:
611     case VALUE:
612     case SCRATCH:
613     CASE_CONST_UNIQUE:
614       return 0;
615 
616     case CONST_VECTOR:
617       if (!same_vector_encodings_p (x, y))
618 	return false;
619       break;
620 
621     case DEBUG_IMPLICIT_PTR:
622       return DEBUG_IMPLICIT_PTR_DECL (x)
623 	     == DEBUG_IMPLICIT_PTR_DECL (y);
624 
625     case DEBUG_PARAMETER_REF:
626       return DEBUG_PARAMETER_REF_DECL (x)
627 	     == DEBUG_PARAMETER_REF_DECL (y);
628 
629     case ENTRY_VALUE:
630       return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
631 
632     default:
633       break;
634     }
635 
636   /* Compare the elements.  If any pair of corresponding elements
637      fail to match, return 0 for the whole thing.  */
638 
639   fmt = GET_RTX_FORMAT (code);
640   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
641     {
642       switch (fmt[i])
643 	{
644 	case 'w':
645 	  if (XWINT (x, i) != XWINT (y, i))
646 	    return 0;
647 	  break;
648 
649 	case 'n':
650 	case 'i':
651 	  if (XINT (x, i) != XINT (y, i))
652 	    {
653 #ifndef GENERATOR_FILE
654 	      if (((code == ASM_OPERANDS && i == 6)
655 		   || (code == ASM_INPUT && i == 1))
656 		  && XINT (x, i) == XINT (y, i))
657 		break;
658 #endif
659 	      return 0;
660 	    }
661 	  break;
662 
663 	case 'p':
664 	  if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
665 	    return 0;
666 	  break;
667 
668 	case 'V':
669 	case 'E':
670 	  /* Two vectors must have the same length.  */
671 	  if (XVECLEN (x, i) != XVECLEN (y, i))
672 	    return 0;
673 
674 	  /* And the corresponding elements must match.  */
675 	  for (j = 0; j < XVECLEN (x, i); j++)
676 	    if (rtx_equal_p (XVECEXP (x, i, j),  XVECEXP (y, i, j)) == 0)
677 	      return 0;
678 	  break;
679 
680 	case 'e':
681 	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
682 	    return 0;
683 	  break;
684 
685 	case 'S':
686 	case 's':
687 	  if ((XSTR (x, i) || XSTR (y, i))
688 	      && (! XSTR (x, i) || ! XSTR (y, i)
689 		  || strcmp (XSTR (x, i), XSTR (y, i))))
690 	    return 0;
691 	  break;
692 
693 	case 'u':
694 	  /* These are just backpointers, so they don't matter.  */
695 	  break;
696 
697 	case '0':
698 	case 't':
699 	  break;
700 
701 	  /* It is believed that rtx's at this level will never
702 	     contain anything but integers and other rtx's,
703 	     except for within LABEL_REFs and SYMBOL_REFs.  */
704 	default:
705 	  gcc_unreachable ();
706 	}
707     }
708   return 1;
709 }
710 
711 /* Return true if all elements of VEC are equal.  */
712 
713 bool
rtvec_all_equal_p(const_rtvec vec)714 rtvec_all_equal_p (const_rtvec vec)
715 {
716   const_rtx first = RTVEC_ELT (vec, 0);
717   /* Optimize the important special case of a vector of constants.
718      The main use of this function is to detect whether every element
719      of CONST_VECTOR is the same.  */
720   switch (GET_CODE (first))
721     {
722     CASE_CONST_UNIQUE:
723       for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
724 	if (first != RTVEC_ELT (vec, i))
725 	  return false;
726       return true;
727 
728     default:
729       for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
730 	if (!rtx_equal_p (first, RTVEC_ELT (vec, i)))
731 	  return false;
732       return true;
733     }
734 }
735 
736 /* Return an indication of which type of insn should have X as a body.
737    In generator files, this can be UNKNOWN if the answer is only known
738    at (GCC) runtime.  Otherwise the value is CODE_LABEL, INSN, CALL_INSN
739    or JUMP_INSN.  */
740 
741 enum rtx_code
classify_insn(rtx x)742 classify_insn (rtx x)
743 {
744   if (LABEL_P (x))
745     return CODE_LABEL;
746   if (GET_CODE (x) == CALL)
747     return CALL_INSN;
748   if (ANY_RETURN_P (x))
749     return JUMP_INSN;
750   if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_LENGTH (x))
751     return JUMP_INSN;
752   if (GET_CODE (x) == SET)
753     {
754       if (GET_CODE (SET_DEST (x)) == PC)
755 	return JUMP_INSN;
756       else if (GET_CODE (SET_SRC (x)) == CALL)
757 	return CALL_INSN;
758       else
759 	return INSN;
760     }
761   if (GET_CODE (x) == PARALLEL)
762     {
763       int j;
764       bool has_return_p = false;
765       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
766 	if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
767 	  return CALL_INSN;
768 	else if (ANY_RETURN_P (XVECEXP (x, 0, j)))
769 	  has_return_p = true;
770 	else if (GET_CODE (XVECEXP (x, 0, j)) == SET
771 		 && GET_CODE (SET_DEST (XVECEXP (x, 0, j))) == PC)
772 	  return JUMP_INSN;
773 	else if (GET_CODE (XVECEXP (x, 0, j)) == SET
774 		 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
775 	  return CALL_INSN;
776       if (has_return_p)
777 	return JUMP_INSN;
778       if (GET_CODE (XVECEXP (x, 0, 0)) == ASM_OPERANDS
779 	  && ASM_OPERANDS_LABEL_LENGTH (XVECEXP (x, 0, 0)))
780 	return JUMP_INSN;
781     }
782 #ifdef GENERATOR_FILE
783   if (GET_CODE (x) == MATCH_OPERAND
784       || GET_CODE (x) == MATCH_OPERATOR
785       || GET_CODE (x) == MATCH_PARALLEL
786       || GET_CODE (x) == MATCH_OP_DUP
787       || GET_CODE (x) == MATCH_DUP
788       || GET_CODE (x) == PARALLEL)
789     return UNKNOWN;
790 #endif
791   return INSN;
792 }
793 
794 /* Comparator of indices based on rtx_alloc_counts.  */
795 
796 static int
rtx_count_cmp(const void * p1,const void * p2)797 rtx_count_cmp (const void *p1, const void *p2)
798 {
799   const unsigned *n1 = (const unsigned *)p1;
800   const unsigned *n2 = (const unsigned *)p2;
801 
802   return rtx_alloc_counts[*n1] - rtx_alloc_counts[*n2];
803 }
804 
805 void
dump_rtx_statistics(void)806 dump_rtx_statistics (void)
807 {
808   int total_counts = 0;
809   int total_sizes = 0;
810 
811   if (! GATHER_STATISTICS)
812     {
813       fprintf (stderr, "No RTX statistics\n");
814       return;
815     }
816 
817   fprintf (stderr, "\nRTX Kind                   Count     Bytes\n");
818   fprintf (stderr, "-------------------------------------------\n");
819 
820   auto_vec<unsigned> indices (LAST_AND_UNUSED_RTX_CODE);
821   for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
822     indices.quick_push (i);
823   indices.qsort (rtx_count_cmp);
824 
825   for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
826     {
827       unsigned j = indices[i];
828       if (rtx_alloc_counts[j])
829 	{
830 	  fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
831 		   GET_RTX_NAME (j),
832 		   SIZE_AMOUNT (rtx_alloc_counts[j]),
833 		   SIZE_AMOUNT (rtx_alloc_sizes[j]));
834 	  total_counts += rtx_alloc_counts[j];
835 	  total_sizes += rtx_alloc_sizes[j];
836 	}
837     }
838 
839   if (rtvec_alloc_counts)
840     {
841       fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", "rtvec",
842 	       SIZE_AMOUNT (rtvec_alloc_counts),
843 	       SIZE_AMOUNT (rtvec_alloc_sizes));
844       total_counts += rtvec_alloc_counts;
845       total_sizes += rtvec_alloc_sizes;
846     }
847   fprintf (stderr, "-----------------------------------------------\n");
848   fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
849 	   "Total", SIZE_AMOUNT (total_counts),
850 	   SIZE_AMOUNT (total_sizes));
851   fprintf (stderr, "-----------------------------------------------\n");
852 }
853 
854 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
855 void
rtl_check_failed_bounds(const_rtx r,int n,const char * file,int line,const char * func)856 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line,
857 			 const char *func)
858 {
859   internal_error
860     ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
861      n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
862      func, trim_filename (file), line);
863 }
864 
865 void
rtl_check_failed_type1(const_rtx r,int n,int c1,const char * file,int line,const char * func)866 rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line,
867 			const char *func)
868 {
869   internal_error
870     ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
871      n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
872      func, trim_filename (file), line);
873 }
874 
875 void
rtl_check_failed_type2(const_rtx r,int n,int c1,int c2,const char * file,int line,const char * func)876 rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file,
877 			int line, const char *func)
878 {
879   internal_error
880     ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
881      n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
882      func, trim_filename (file), line);
883 }
884 
885 void
rtl_check_failed_code1(const_rtx r,enum rtx_code code,const char * file,int line,const char * func)886 rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file,
887 			int line, const char *func)
888 {
889   internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
890 		  GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
891 		  trim_filename (file), line);
892 }
893 
894 void
rtl_check_failed_code2(const_rtx r,enum rtx_code code1,enum rtx_code code2,const char * file,int line,const char * func)895 rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
896 			const char *file, int line, const char *func)
897 {
898   internal_error
899     ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
900      GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
901      func, trim_filename (file), line);
902 }
903 
904 void
rtl_check_failed_code3(const_rtx r,enum rtx_code code1,enum rtx_code code2,enum rtx_code code3,const char * file,int line,const char * func)905 rtl_check_failed_code3 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
906 			enum rtx_code code3, const char *file, int line,
907 			const char *func)
908 {
909   internal_error
910     ("RTL check: expected code '%s', '%s' or '%s', have '%s' in %s, at %s:%d",
911      GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (code3),
912      GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
913 }
914 
915 void
rtl_check_failed_code_mode(const_rtx r,enum rtx_code code,machine_mode mode,bool not_mode,const char * file,int line,const char * func)916 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
917 			    bool not_mode, const char *file, int line,
918 			    const char *func)
919 {
920   internal_error ((not_mode
921 		   ? ("RTL check: expected code '%s' and not mode '%s', "
922 		      "have code '%s' and mode '%s' in %s, at %s:%d")
923 		   : ("RTL check: expected code '%s' and mode '%s', "
924 		      "have code '%s' and mode '%s' in %s, at %s:%d")),
925 		  GET_RTX_NAME (code), GET_MODE_NAME (mode),
926 		  GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
927 		  func, trim_filename (file), line);
928 }
929 
930 /* Report that line LINE of FILE tried to access the block symbol fields
931    of a non-block symbol.  FUNC is the function that contains the line.  */
932 
933 void
rtl_check_failed_block_symbol(const char * file,int line,const char * func)934 rtl_check_failed_block_symbol (const char *file, int line, const char *func)
935 {
936   internal_error
937     ("RTL check: attempt to treat non-block symbol as a block symbol "
938      "in %s, at %s:%d", func, trim_filename (file), line);
939 }
940 
941 /* XXX Maybe print the vector?  */
942 void
cwi_check_failed_bounds(const_rtx x,int n,const char * file,int line,const char * func)943 cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line,
944 			 const char *func)
945 {
946   internal_error
947     ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d",
948      n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line);
949 }
950 
951 /* XXX Maybe print the vector?  */
952 void
rtvec_check_failed_bounds(const_rtvec r,int n,const char * file,int line,const char * func)953 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line,
954 			   const char *func)
955 {
956   internal_error
957     ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
958      n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
959 }
960 #endif /* ENABLE_RTL_CHECKING */
961 
962 #if defined ENABLE_RTL_FLAG_CHECKING
963 void
rtl_check_failed_flag(const char * name,const_rtx r,const char * file,int line,const char * func)964 rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
965 		       int line, const char *func)
966 {
967   internal_error
968     ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
969      name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
970 }
971 #endif /* ENABLE_RTL_FLAG_CHECKING */
972