]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rtl.c
expander: Optimize store_expr from STRING_CST [PR95052]
[thirdparty/gcc.git] / gcc / rtl.c
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 \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 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 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
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
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 \f
259 /* Return true if ORIG is a sharable CONST. */
260
261 bool
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
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
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 \f
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 \f
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
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 DEBUG_IMPLICIT_PTR:
470 return DEBUG_IMPLICIT_PTR_DECL (x)
471 == DEBUG_IMPLICIT_PTR_DECL (y);
472
473 case DEBUG_PARAMETER_REF:
474 return DEBUG_PARAMETER_REF_DECL (x)
475 == DEBUG_PARAMETER_REF_DECL (y);
476
477 case ENTRY_VALUE:
478 return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
479
480 default:
481 break;
482 }
483
484 /* Compare the elements. If any pair of corresponding elements
485 fail to match, return 0 for the whole thing. */
486
487 fmt = GET_RTX_FORMAT (code);
488 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
489 {
490 switch (fmt[i])
491 {
492 case 'w':
493 if (XWINT (x, i) != XWINT (y, i))
494 return 0;
495 break;
496
497 case 'n':
498 case 'i':
499 if (XINT (x, i) != XINT (y, i))
500 {
501 #ifndef GENERATOR_FILE
502 if (((code == ASM_OPERANDS && i == 6)
503 || (code == ASM_INPUT && i == 1))
504 && XINT (x, i) == XINT (y, i))
505 break;
506 #endif
507 return 0;
508 }
509 break;
510
511 case 'p':
512 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
513 return 0;
514 break;
515
516 case 'V':
517 case 'E':
518 /* Two vectors must have the same length. */
519 if (XVECLEN (x, i) != XVECLEN (y, i))
520 return 0;
521
522 /* And the corresponding elements must match. */
523 for (j = 0; j < XVECLEN (x, i); j++)
524 if (rtx_equal_p_cb (XVECEXP (x, i, j),
525 XVECEXP (y, i, j), cb) == 0)
526 return 0;
527 break;
528
529 case 'e':
530 if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0)
531 return 0;
532 break;
533
534 case 'S':
535 case 's':
536 if ((XSTR (x, i) || XSTR (y, i))
537 && (! XSTR (x, i) || ! XSTR (y, i)
538 || strcmp (XSTR (x, i), XSTR (y, i))))
539 return 0;
540 break;
541
542 case 'u':
543 /* These are just backpointers, so they don't matter. */
544 break;
545
546 case '0':
547 case 't':
548 break;
549
550 /* It is believed that rtx's at this level will never
551 contain anything but integers and other rtx's,
552 except for within LABEL_REFs and SYMBOL_REFs. */
553 default:
554 gcc_unreachable ();
555 }
556 }
557 return 1;
558 }
559
560 /* Return 1 if X and Y are identical-looking rtx's.
561 This is the Lisp function EQUAL for rtx arguments.
562 Whenever changing this function check if rtx_equal_p_cb above doesn't need
563 changing as well. */
564
565 int
566 rtx_equal_p (const_rtx x, const_rtx y)
567 {
568 int i;
569 int j;
570 enum rtx_code code;
571 const char *fmt;
572
573 if (x == y)
574 return 1;
575 if (x == 0 || y == 0)
576 return 0;
577
578 code = GET_CODE (x);
579 /* Rtx's of different codes cannot be equal. */
580 if (code != GET_CODE (y))
581 return 0;
582
583 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
584 (REG:SI x) and (REG:HI x) are NOT equivalent. */
585
586 if (GET_MODE (x) != GET_MODE (y))
587 return 0;
588
589 /* MEMs referring to different address space are not equivalent. */
590 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
591 return 0;
592
593 /* Some RTL can be compared nonrecursively. */
594 switch (code)
595 {
596 case REG:
597 return (REGNO (x) == REGNO (y));
598
599 case LABEL_REF:
600 return label_ref_label (x) == label_ref_label (y);
601
602 case SYMBOL_REF:
603 return XSTR (x, 0) == XSTR (y, 0);
604
605 case DEBUG_EXPR:
606 case VALUE:
607 case SCRATCH:
608 CASE_CONST_UNIQUE:
609 return 0;
610
611 case DEBUG_IMPLICIT_PTR:
612 return DEBUG_IMPLICIT_PTR_DECL (x)
613 == DEBUG_IMPLICIT_PTR_DECL (y);
614
615 case DEBUG_PARAMETER_REF:
616 return DEBUG_PARAMETER_REF_DECL (x)
617 == DEBUG_PARAMETER_REF_DECL (y);
618
619 case ENTRY_VALUE:
620 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
621
622 default:
623 break;
624 }
625
626 /* Compare the elements. If any pair of corresponding elements
627 fail to match, return 0 for the whole thing. */
628
629 fmt = GET_RTX_FORMAT (code);
630 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
631 {
632 switch (fmt[i])
633 {
634 case 'w':
635 if (XWINT (x, i) != XWINT (y, i))
636 return 0;
637 break;
638
639 case 'n':
640 case 'i':
641 if (XINT (x, i) != XINT (y, i))
642 {
643 #ifndef GENERATOR_FILE
644 if (((code == ASM_OPERANDS && i == 6)
645 || (code == ASM_INPUT && i == 1))
646 && XINT (x, i) == XINT (y, i))
647 break;
648 #endif
649 return 0;
650 }
651 break;
652
653 case 'p':
654 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
655 return 0;
656 break;
657
658 case 'V':
659 case 'E':
660 /* Two vectors must have the same length. */
661 if (XVECLEN (x, i) != XVECLEN (y, i))
662 return 0;
663
664 /* And the corresponding elements must match. */
665 for (j = 0; j < XVECLEN (x, i); j++)
666 if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
667 return 0;
668 break;
669
670 case 'e':
671 if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
672 return 0;
673 break;
674
675 case 'S':
676 case 's':
677 if ((XSTR (x, i) || XSTR (y, i))
678 && (! XSTR (x, i) || ! XSTR (y, i)
679 || strcmp (XSTR (x, i), XSTR (y, i))))
680 return 0;
681 break;
682
683 case 'u':
684 /* These are just backpointers, so they don't matter. */
685 break;
686
687 case '0':
688 case 't':
689 break;
690
691 /* It is believed that rtx's at this level will never
692 contain anything but integers and other rtx's,
693 except for within LABEL_REFs and SYMBOL_REFs. */
694 default:
695 gcc_unreachable ();
696 }
697 }
698 return 1;
699 }
700
701 /* Return true if all elements of VEC are equal. */
702
703 bool
704 rtvec_all_equal_p (const_rtvec vec)
705 {
706 const_rtx first = RTVEC_ELT (vec, 0);
707 /* Optimize the important special case of a vector of constants.
708 The main use of this function is to detect whether every element
709 of CONST_VECTOR is the same. */
710 switch (GET_CODE (first))
711 {
712 CASE_CONST_UNIQUE:
713 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
714 if (first != RTVEC_ELT (vec, i))
715 return false;
716 return true;
717
718 default:
719 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
720 if (!rtx_equal_p (first, RTVEC_ELT (vec, i)))
721 return false;
722 return true;
723 }
724 }
725
726 /* Return an indication of which type of insn should have X as a body.
727 In generator files, this can be UNKNOWN if the answer is only known
728 at (GCC) runtime. Otherwise the value is CODE_LABEL, INSN, CALL_INSN
729 or JUMP_INSN. */
730
731 enum rtx_code
732 classify_insn (rtx x)
733 {
734 if (LABEL_P (x))
735 return CODE_LABEL;
736 if (GET_CODE (x) == CALL)
737 return CALL_INSN;
738 if (ANY_RETURN_P (x))
739 return JUMP_INSN;
740 if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_VEC (x))
741 return JUMP_INSN;
742 if (GET_CODE (x) == SET)
743 {
744 if (GET_CODE (SET_DEST (x)) == PC)
745 return JUMP_INSN;
746 else if (GET_CODE (SET_SRC (x)) == CALL)
747 return CALL_INSN;
748 else
749 return INSN;
750 }
751 if (GET_CODE (x) == PARALLEL)
752 {
753 int j;
754 bool has_return_p = false;
755 for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
756 if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
757 return CALL_INSN;
758 else if (ANY_RETURN_P (XVECEXP (x, 0, j)))
759 has_return_p = true;
760 else if (GET_CODE (XVECEXP (x, 0, j)) == SET
761 && GET_CODE (SET_DEST (XVECEXP (x, 0, j))) == PC)
762 return JUMP_INSN;
763 else if (GET_CODE (XVECEXP (x, 0, j)) == SET
764 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
765 return CALL_INSN;
766 if (has_return_p)
767 return JUMP_INSN;
768 if (GET_CODE (XVECEXP (x, 0, 0)) == ASM_OPERANDS
769 && ASM_OPERANDS_LABEL_VEC (XVECEXP (x, 0, 0)))
770 return JUMP_INSN;
771 }
772 #ifdef GENERATOR_FILE
773 if (GET_CODE (x) == MATCH_OPERAND
774 || GET_CODE (x) == MATCH_OPERATOR
775 || GET_CODE (x) == MATCH_PARALLEL
776 || GET_CODE (x) == MATCH_OP_DUP
777 || GET_CODE (x) == MATCH_DUP
778 || GET_CODE (x) == PARALLEL)
779 return UNKNOWN;
780 #endif
781 return INSN;
782 }
783
784 /* Comparator of indices based on rtx_alloc_counts. */
785
786 static int
787 rtx_count_cmp (const void *p1, const void *p2)
788 {
789 const unsigned *n1 = (const unsigned *)p1;
790 const unsigned *n2 = (const unsigned *)p2;
791
792 return rtx_alloc_counts[*n1] - rtx_alloc_counts[*n2];
793 }
794
795 void
796 dump_rtx_statistics (void)
797 {
798 int total_counts = 0;
799 int total_sizes = 0;
800
801 if (! GATHER_STATISTICS)
802 {
803 fprintf (stderr, "No RTX statistics\n");
804 return;
805 }
806
807 fprintf (stderr, "\nRTX Kind Count Bytes\n");
808 fprintf (stderr, "-------------------------------------------\n");
809
810 auto_vec<unsigned> indices (LAST_AND_UNUSED_RTX_CODE);
811 for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
812 indices.quick_push (i);
813 indices.qsort (rtx_count_cmp);
814
815 for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
816 {
817 unsigned j = indices[i];
818 if (rtx_alloc_counts[j])
819 {
820 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
821 GET_RTX_NAME (j),
822 SIZE_AMOUNT (rtx_alloc_counts[j]),
823 SIZE_AMOUNT (rtx_alloc_sizes[j]));
824 total_counts += rtx_alloc_counts[j];
825 total_sizes += rtx_alloc_sizes[j];
826 }
827 }
828
829 if (rtvec_alloc_counts)
830 {
831 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", "rtvec",
832 SIZE_AMOUNT (rtvec_alloc_counts),
833 SIZE_AMOUNT (rtvec_alloc_sizes));
834 total_counts += rtvec_alloc_counts;
835 total_sizes += rtvec_alloc_sizes;
836 }
837 fprintf (stderr, "-----------------------------------------------\n");
838 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
839 "Total", SIZE_AMOUNT (total_counts),
840 SIZE_AMOUNT (total_sizes));
841 fprintf (stderr, "-----------------------------------------------\n");
842 }
843 \f
844 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
845 void
846 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line,
847 const char *func)
848 {
849 internal_error
850 ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
851 n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
852 func, trim_filename (file), line);
853 }
854
855 void
856 rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line,
857 const char *func)
858 {
859 internal_error
860 ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
861 n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
862 func, trim_filename (file), line);
863 }
864
865 void
866 rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file,
867 int line, const char *func)
868 {
869 internal_error
870 ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
871 n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
872 func, trim_filename (file), line);
873 }
874
875 void
876 rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file,
877 int line, const char *func)
878 {
879 internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
880 GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
881 trim_filename (file), line);
882 }
883
884 void
885 rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
886 const char *file, int line, const char *func)
887 {
888 internal_error
889 ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
890 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
891 func, trim_filename (file), line);
892 }
893
894 void
895 rtl_check_failed_code3 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
896 enum rtx_code code3, const char *file, int line,
897 const char *func)
898 {
899 internal_error
900 ("RTL check: expected code '%s', '%s' or '%s', have '%s' in %s, at %s:%d",
901 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (code3),
902 GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
903 }
904
905 void
906 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
907 bool not_mode, const char *file, int line,
908 const char *func)
909 {
910 internal_error ((not_mode
911 ? ("RTL check: expected code '%s' and not mode '%s', "
912 "have code '%s' and mode '%s' in %s, at %s:%d")
913 : ("RTL check: expected code '%s' and mode '%s', "
914 "have code '%s' and mode '%s' in %s, at %s:%d")),
915 GET_RTX_NAME (code), GET_MODE_NAME (mode),
916 GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
917 func, trim_filename (file), line);
918 }
919
920 /* Report that line LINE of FILE tried to access the block symbol fields
921 of a non-block symbol. FUNC is the function that contains the line. */
922
923 void
924 rtl_check_failed_block_symbol (const char *file, int line, const char *func)
925 {
926 internal_error
927 ("RTL check: attempt to treat non-block symbol as a block symbol "
928 "in %s, at %s:%d", func, trim_filename (file), line);
929 }
930
931 /* XXX Maybe print the vector? */
932 void
933 cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line,
934 const char *func)
935 {
936 internal_error
937 ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d",
938 n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line);
939 }
940
941 /* XXX Maybe print the vector? */
942 void
943 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line,
944 const char *func)
945 {
946 internal_error
947 ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
948 n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
949 }
950 #endif /* ENABLE_RTL_CHECKING */
951
952 #if defined ENABLE_RTL_FLAG_CHECKING
953 void
954 rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
955 int line, const char *func)
956 {
957 internal_error
958 ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
959 name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
960 }
961 #endif /* ENABLE_RTL_FLAG_CHECKING */