]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rtl.c
Update copyright years.
[thirdparty/gcc.git] / gcc / rtl.c
1 /* RTL utility routines.
2 Copyright (C) 1987-2019 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 \f
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 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 \f
157 /* Allocate an rtx vector of N elements.
158 Store the length, and initialize all elements to zero. */
159
160 rtvec
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
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
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
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 /* We want to clear everything up to the FLD array. Normally, this
223 is one int, but we don't want to assume that and it isn't very
224 portable anyway; this is. */
225
226 memset (rt, 0, RTX_HDR_SIZE);
227 PUT_CODE (rt, code);
228
229 if (GATHER_STATISTICS)
230 {
231 rtx_alloc_counts[code]++;
232 rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
233 }
234
235 return rt;
236 }
237
238 /* Allocate an rtx of code CODE. The CODE is stored in the rtx;
239 all the rest is initialized to zero. */
240
241 rtx
242 rtx_alloc (RTX_CODE code MEM_STAT_DECL)
243 {
244 return rtx_alloc_stat_v (code PASS_MEM_STAT, 0);
245 }
246
247 /* Write the wide constant X to OUTFILE. */
248
249 void
250 cwi_output_hex (FILE *outfile, const_rtx x)
251 {
252 int i = CWI_GET_NUM_ELEM (x);
253 gcc_assert (i > 0);
254 if (CWI_ELT (x, i - 1) == 0)
255 /* The HOST_WIDE_INT_PRINT_HEX prepends a 0x only if the val is
256 non zero. We want all numbers to have a 0x prefix. */
257 fprintf (outfile, "0x");
258 fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i));
259 while (--i >= 0)
260 fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i));
261 }
262
263 \f
264 /* Return true if ORIG is a sharable CONST. */
265
266 bool
267 shared_const_p (const_rtx orig)
268 {
269 gcc_assert (GET_CODE (orig) == CONST);
270
271 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
272 a LABEL_REF, it isn't sharable. */
273 poly_int64 offset;
274 return (GET_CODE (XEXP (orig, 0)) == PLUS
275 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
276 && poly_int_rtx_p (XEXP (XEXP (orig, 0), 1), &offset));
277 }
278
279
280 /* Create a new copy of an rtx.
281 Recursively copies the operands of the rtx,
282 except for those few rtx codes that are sharable. */
283
284 rtx
285 copy_rtx (rtx orig)
286 {
287 rtx copy;
288 int i, j;
289 RTX_CODE code;
290 const char *format_ptr;
291
292 code = GET_CODE (orig);
293
294 switch (code)
295 {
296 case REG:
297 case DEBUG_EXPR:
298 case VALUE:
299 CASE_CONST_ANY:
300 case SYMBOL_REF:
301 case CODE_LABEL:
302 case PC:
303 case CC0:
304 case RETURN:
305 case SIMPLE_RETURN:
306 case SCRATCH:
307 /* SCRATCH must be shared because they represent distinct values. */
308 return orig;
309 case CLOBBER:
310 /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
311 clobbers or clobbers of hard registers that originated as pseudos.
312 This is needed to allow safe register renaming. */
313 if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER
314 && ORIGINAL_REGNO (XEXP (orig, 0)) == REGNO (XEXP (orig, 0)))
315 return orig;
316 break;
317
318 case CLOBBER_HIGH:
319 gcc_assert (REG_P (XEXP (orig, 0)));
320 return orig;
321
322 case CONST:
323 if (shared_const_p (orig))
324 return orig;
325 break;
326
327 /* A MEM with a constant address is not sharable. The problem is that
328 the constant address may need to be reloaded. If the mem is shared,
329 then reloading one copy of this mem will cause all copies to appear
330 to have been reloaded. */
331
332 default:
333 break;
334 }
335
336 /* Copy the various flags, fields, and other information. We assume
337 that all fields need copying, and then clear the fields that should
338 not be copied. That is the sensible default behavior, and forces
339 us to explicitly document why we are *not* copying a flag. */
340 copy = shallow_copy_rtx (orig);
341
342 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
343
344 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
345 switch (*format_ptr++)
346 {
347 case 'e':
348 if (XEXP (orig, i) != NULL)
349 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
350 break;
351
352 case 'E':
353 case 'V':
354 if (XVEC (orig, i) != NULL)
355 {
356 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
357 for (j = 0; j < XVECLEN (copy, i); j++)
358 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
359 }
360 break;
361
362 case 't':
363 case 'w':
364 case 'i':
365 case 'p':
366 case 's':
367 case 'S':
368 case 'T':
369 case 'u':
370 case 'B':
371 case '0':
372 /* These are left unchanged. */
373 break;
374
375 default:
376 gcc_unreachable ();
377 }
378 return copy;
379 }
380
381 /* Create a new copy of an rtx. Only copy just one level. */
382
383 rtx
384 shallow_copy_rtx (const_rtx orig MEM_STAT_DECL)
385 {
386 const unsigned int size = rtx_size (orig);
387 rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT);
388 memcpy (copy, orig, size);
389 switch (GET_CODE (orig))
390 {
391 /* RTX codes copy_rtx_if_shared_1 considers are shareable,
392 the used flag is often used for other purposes. */
393 case REG:
394 case DEBUG_EXPR:
395 case VALUE:
396 CASE_CONST_ANY:
397 case SYMBOL_REF:
398 case CODE_LABEL:
399 case PC:
400 case CC0:
401 case RETURN:
402 case SIMPLE_RETURN:
403 case SCRATCH:
404 break;
405 default:
406 /* For all other RTXes clear the used flag on the copy. */
407 RTX_FLAG (copy, used) = 0;
408 break;
409 }
410 return copy;
411 }
412 \f
413 /* Nonzero when we are generating CONCATs. */
414 int generating_concat_p;
415
416 /* Nonzero when we are expanding trees to RTL. */
417 int currently_expanding_to_rtl;
418
419 \f
420
421 /* Same as rtx_equal_p, but call CB on each pair of rtx if CB is not NULL.
422 When the callback returns true, we continue with the new pair.
423 Whenever changing this function check if rtx_equal_p below doesn't need
424 changing as well. */
425
426 int
427 rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
428 {
429 int i;
430 int j;
431 enum rtx_code code;
432 const char *fmt;
433 rtx nx, ny;
434
435 if (x == y)
436 return 1;
437 if (x == 0 || y == 0)
438 return 0;
439
440 /* Invoke the callback first. */
441 if (cb != NULL
442 && ((*cb) (&x, &y, &nx, &ny)))
443 return rtx_equal_p_cb (nx, ny, cb);
444
445 code = GET_CODE (x);
446 /* Rtx's of different codes cannot be equal. */
447 if (code != GET_CODE (y))
448 return 0;
449
450 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
451 (REG:SI x) and (REG:HI x) are NOT equivalent. */
452
453 if (GET_MODE (x) != GET_MODE (y))
454 return 0;
455
456 /* MEMs referring to different address space are not equivalent. */
457 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
458 return 0;
459
460 /* Some RTL can be compared nonrecursively. */
461 switch (code)
462 {
463 case REG:
464 return (REGNO (x) == REGNO (y));
465
466 case LABEL_REF:
467 return label_ref_label (x) == label_ref_label (y);
468
469 case SYMBOL_REF:
470 return XSTR (x, 0) == XSTR (y, 0);
471
472 case DEBUG_EXPR:
473 case VALUE:
474 case SCRATCH:
475 CASE_CONST_UNIQUE:
476 return 0;
477
478 case DEBUG_IMPLICIT_PTR:
479 return DEBUG_IMPLICIT_PTR_DECL (x)
480 == DEBUG_IMPLICIT_PTR_DECL (y);
481
482 case DEBUG_PARAMETER_REF:
483 return DEBUG_PARAMETER_REF_DECL (x)
484 == DEBUG_PARAMETER_REF_DECL (y);
485
486 case ENTRY_VALUE:
487 return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
488
489 default:
490 break;
491 }
492
493 /* Compare the elements. If any pair of corresponding elements
494 fail to match, return 0 for the whole thing. */
495
496 fmt = GET_RTX_FORMAT (code);
497 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
498 {
499 switch (fmt[i])
500 {
501 case 'w':
502 if (XWINT (x, i) != XWINT (y, i))
503 return 0;
504 break;
505
506 case 'n':
507 case 'i':
508 if (XINT (x, i) != XINT (y, i))
509 {
510 #ifndef GENERATOR_FILE
511 if (((code == ASM_OPERANDS && i == 6)
512 || (code == ASM_INPUT && i == 1))
513 && XINT (x, i) == XINT (y, i))
514 break;
515 #endif
516 return 0;
517 }
518 break;
519
520 case 'p':
521 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
522 return 0;
523 break;
524
525 case 'V':
526 case 'E':
527 /* Two vectors must have the same length. */
528 if (XVECLEN (x, i) != XVECLEN (y, i))
529 return 0;
530
531 /* And the corresponding elements must match. */
532 for (j = 0; j < XVECLEN (x, i); j++)
533 if (rtx_equal_p_cb (XVECEXP (x, i, j),
534 XVECEXP (y, i, j), cb) == 0)
535 return 0;
536 break;
537
538 case 'e':
539 if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0)
540 return 0;
541 break;
542
543 case 'S':
544 case 's':
545 if ((XSTR (x, i) || XSTR (y, i))
546 && (! XSTR (x, i) || ! XSTR (y, i)
547 || strcmp (XSTR (x, i), XSTR (y, i))))
548 return 0;
549 break;
550
551 case 'u':
552 /* These are just backpointers, so they don't matter. */
553 break;
554
555 case '0':
556 case 't':
557 break;
558
559 /* It is believed that rtx's at this level will never
560 contain anything but integers and other rtx's,
561 except for within LABEL_REFs and SYMBOL_REFs. */
562 default:
563 gcc_unreachable ();
564 }
565 }
566 return 1;
567 }
568
569 /* Return 1 if X and Y are identical-looking rtx's.
570 This is the Lisp function EQUAL for rtx arguments.
571 Whenever changing this function check if rtx_equal_p_cb above doesn't need
572 changing as well. */
573
574 int
575 rtx_equal_p (const_rtx x, const_rtx y)
576 {
577 int i;
578 int j;
579 enum rtx_code code;
580 const char *fmt;
581
582 if (x == y)
583 return 1;
584 if (x == 0 || y == 0)
585 return 0;
586
587 code = GET_CODE (x);
588 /* Rtx's of different codes cannot be equal. */
589 if (code != GET_CODE (y))
590 return 0;
591
592 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
593 (REG:SI x) and (REG:HI x) are NOT equivalent. */
594
595 if (GET_MODE (x) != GET_MODE (y))
596 return 0;
597
598 /* MEMs referring to different address space are not equivalent. */
599 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
600 return 0;
601
602 /* Some RTL can be compared nonrecursively. */
603 switch (code)
604 {
605 case REG:
606 return (REGNO (x) == REGNO (y));
607
608 case LABEL_REF:
609 return label_ref_label (x) == label_ref_label (y);
610
611 case SYMBOL_REF:
612 return XSTR (x, 0) == XSTR (y, 0);
613
614 case DEBUG_EXPR:
615 case VALUE:
616 case SCRATCH:
617 CASE_CONST_UNIQUE:
618 return 0;
619
620 case DEBUG_IMPLICIT_PTR:
621 return DEBUG_IMPLICIT_PTR_DECL (x)
622 == DEBUG_IMPLICIT_PTR_DECL (y);
623
624 case DEBUG_PARAMETER_REF:
625 return DEBUG_PARAMETER_REF_DECL (x)
626 == DEBUG_PARAMETER_REF_DECL (y);
627
628 case ENTRY_VALUE:
629 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
630
631 default:
632 break;
633 }
634
635 /* Compare the elements. If any pair of corresponding elements
636 fail to match, return 0 for the whole thing. */
637
638 fmt = GET_RTX_FORMAT (code);
639 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
640 {
641 switch (fmt[i])
642 {
643 case 'w':
644 if (XWINT (x, i) != XWINT (y, i))
645 return 0;
646 break;
647
648 case 'n':
649 case 'i':
650 if (XINT (x, i) != XINT (y, i))
651 {
652 #ifndef GENERATOR_FILE
653 if (((code == ASM_OPERANDS && i == 6)
654 || (code == ASM_INPUT && i == 1))
655 && XINT (x, i) == XINT (y, i))
656 break;
657 #endif
658 return 0;
659 }
660 break;
661
662 case 'p':
663 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
664 return 0;
665 break;
666
667 case 'V':
668 case 'E':
669 /* Two vectors must have the same length. */
670 if (XVECLEN (x, i) != XVECLEN (y, i))
671 return 0;
672
673 /* And the corresponding elements must match. */
674 for (j = 0; j < XVECLEN (x, i); j++)
675 if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
676 return 0;
677 break;
678
679 case 'e':
680 if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
681 return 0;
682 break;
683
684 case 'S':
685 case 's':
686 if ((XSTR (x, i) || XSTR (y, i))
687 && (! XSTR (x, i) || ! XSTR (y, i)
688 || strcmp (XSTR (x, i), XSTR (y, i))))
689 return 0;
690 break;
691
692 case 'u':
693 /* These are just backpointers, so they don't matter. */
694 break;
695
696 case '0':
697 case 't':
698 break;
699
700 /* It is believed that rtx's at this level will never
701 contain anything but integers and other rtx's,
702 except for within LABEL_REFs and SYMBOL_REFs. */
703 default:
704 gcc_unreachable ();
705 }
706 }
707 return 1;
708 }
709
710 /* Return true if all elements of VEC are equal. */
711
712 bool
713 rtvec_all_equal_p (const_rtvec vec)
714 {
715 const_rtx first = RTVEC_ELT (vec, 0);
716 /* Optimize the important special case of a vector of constants.
717 The main use of this function is to detect whether every element
718 of CONST_VECTOR is the same. */
719 switch (GET_CODE (first))
720 {
721 CASE_CONST_UNIQUE:
722 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
723 if (first != RTVEC_ELT (vec, i))
724 return false;
725 return true;
726
727 default:
728 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
729 if (!rtx_equal_p (first, RTVEC_ELT (vec, i)))
730 return false;
731 return true;
732 }
733 }
734
735 /* Return an indication of which type of insn should have X as a body.
736 In generator files, this can be UNKNOWN if the answer is only known
737 at (GCC) runtime. Otherwise the value is CODE_LABEL, INSN, CALL_INSN
738 or JUMP_INSN. */
739
740 enum rtx_code
741 classify_insn (rtx x)
742 {
743 if (LABEL_P (x))
744 return CODE_LABEL;
745 if (GET_CODE (x) == CALL)
746 return CALL_INSN;
747 if (ANY_RETURN_P (x))
748 return JUMP_INSN;
749 if (GET_CODE (x) == SET)
750 {
751 if (GET_CODE (SET_DEST (x)) == PC)
752 return JUMP_INSN;
753 else if (GET_CODE (SET_SRC (x)) == CALL)
754 return CALL_INSN;
755 else
756 return INSN;
757 }
758 if (GET_CODE (x) == PARALLEL)
759 {
760 int j;
761 bool has_return_p = false;
762 for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
763 if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
764 return CALL_INSN;
765 else if (ANY_RETURN_P (XVECEXP (x, 0, j)))
766 has_return_p = true;
767 else if (GET_CODE (XVECEXP (x, 0, j)) == SET
768 && GET_CODE (SET_DEST (XVECEXP (x, 0, j))) == PC)
769 return JUMP_INSN;
770 else if (GET_CODE (XVECEXP (x, 0, j)) == SET
771 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
772 return CALL_INSN;
773 if (has_return_p)
774 return JUMP_INSN;
775 }
776 #ifdef GENERATOR_FILE
777 if (GET_CODE (x) == MATCH_OPERAND
778 || GET_CODE (x) == MATCH_OPERATOR
779 || GET_CODE (x) == MATCH_PARALLEL
780 || GET_CODE (x) == MATCH_OP_DUP
781 || GET_CODE (x) == MATCH_DUP
782 || GET_CODE (x) == PARALLEL)
783 return UNKNOWN;
784 #endif
785 return INSN;
786 }
787
788 /* Comparator of indices based on rtx_alloc_counts. */
789
790 static int
791 rtx_count_cmp (const void *p1, const void *p2)
792 {
793 const unsigned *n1 = (const unsigned *)p1;
794 const unsigned *n2 = (const unsigned *)p2;
795
796 return rtx_alloc_counts[*n1] - rtx_alloc_counts[*n2];
797 }
798
799 void
800 dump_rtx_statistics (void)
801 {
802 int total_counts = 0;
803 int total_sizes = 0;
804
805 if (! GATHER_STATISTICS)
806 {
807 fprintf (stderr, "No RTX statistics\n");
808 return;
809 }
810
811 fprintf (stderr, "\nRTX Kind Count Bytes\n");
812 fprintf (stderr, "-------------------------------------------\n");
813
814 auto_vec<unsigned> indices (LAST_AND_UNUSED_RTX_CODE);
815 for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
816 indices.quick_push (i);
817 indices.qsort (rtx_count_cmp);
818
819 for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
820 {
821 unsigned j = indices[i];
822 if (rtx_alloc_counts[j])
823 {
824 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
825 GET_RTX_NAME (j),
826 SIZE_AMOUNT (rtx_alloc_counts[j]),
827 SIZE_AMOUNT (rtx_alloc_sizes[j]));
828 total_counts += rtx_alloc_counts[j];
829 total_sizes += rtx_alloc_sizes[j];
830 }
831 }
832
833 if (rtvec_alloc_counts)
834 {
835 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", "rtvec",
836 SIZE_AMOUNT (rtvec_alloc_counts),
837 SIZE_AMOUNT (rtvec_alloc_sizes));
838 total_counts += rtvec_alloc_counts;
839 total_sizes += rtvec_alloc_sizes;
840 }
841 fprintf (stderr, "-----------------------------------------------\n");
842 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
843 "Total", SIZE_AMOUNT (total_counts),
844 SIZE_AMOUNT (total_sizes));
845 fprintf (stderr, "-----------------------------------------------\n");
846 }
847 \f
848 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
849 void
850 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line,
851 const char *func)
852 {
853 internal_error
854 ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
855 n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
856 func, trim_filename (file), line);
857 }
858
859 void
860 rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line,
861 const char *func)
862 {
863 internal_error
864 ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
865 n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
866 func, trim_filename (file), line);
867 }
868
869 void
870 rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file,
871 int line, const char *func)
872 {
873 internal_error
874 ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
875 n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
876 func, trim_filename (file), line);
877 }
878
879 void
880 rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file,
881 int line, const char *func)
882 {
883 internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
884 GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
885 trim_filename (file), line);
886 }
887
888 void
889 rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
890 const char *file, int line, const char *func)
891 {
892 internal_error
893 ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
894 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
895 func, trim_filename (file), line);
896 }
897
898 void
899 rtl_check_failed_code3 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
900 enum rtx_code code3, const char *file, int line,
901 const char *func)
902 {
903 internal_error
904 ("RTL check: expected code '%s', '%s' or '%s', have '%s' in %s, at %s:%d",
905 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (code3),
906 GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
907 }
908
909 void
910 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
911 bool not_mode, const char *file, int line,
912 const char *func)
913 {
914 internal_error ((not_mode
915 ? ("RTL check: expected code '%s' and not mode '%s', "
916 "have code '%s' and mode '%s' in %s, at %s:%d")
917 : ("RTL check: expected code '%s' and mode '%s', "
918 "have code '%s' and mode '%s' in %s, at %s:%d")),
919 GET_RTX_NAME (code), GET_MODE_NAME (mode),
920 GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
921 func, trim_filename (file), line);
922 }
923
924 /* Report that line LINE of FILE tried to access the block symbol fields
925 of a non-block symbol. FUNC is the function that contains the line. */
926
927 void
928 rtl_check_failed_block_symbol (const char *file, int line, const char *func)
929 {
930 internal_error
931 ("RTL check: attempt to treat non-block symbol as a block symbol "
932 "in %s, at %s:%d", func, trim_filename (file), line);
933 }
934
935 /* XXX Maybe print the vector? */
936 void
937 cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line,
938 const char *func)
939 {
940 internal_error
941 ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d",
942 n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line);
943 }
944
945 /* XXX Maybe print the vector? */
946 void
947 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line,
948 const char *func)
949 {
950 internal_error
951 ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
952 n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
953 }
954 #endif /* ENABLE_RTL_CHECKING */
955
956 #if defined ENABLE_RTL_FLAG_CHECKING
957 void
958 rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
959 int line, const char *func)
960 {
961 internal_error
962 ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
963 name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
964 }
965 #endif /* ENABLE_RTL_FLAG_CHECKING */