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