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