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