]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rtl.c
libgo: update to Go 1.12.2
[thirdparty/gcc.git] / gcc / rtl.c
CommitLineData
875d8740 1/* RTL utility routines.
fbd26352 2 Copyright (C) 1987-2019 Free Software Foundation, Inc.
759bebca 3
f12b58b3 4This file is part of GCC.
759bebca 5
f12b58b3 6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8c4c00c1 8Software Foundation; either version 3, or (at your option) any later
f12b58b3 9version.
759bebca 10
f12b58b3 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
759bebca 15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
759bebca 19
690ff52f 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
759bebca 25#include "config.h"
690ff52f 26#endif
27
405711de 28#include "system.h"
805e22b2 29#include "coretypes.h"
30#include "tm.h"
881f903e 31#include "rtl.h"
690abe5d 32#ifdef GENERATOR_FILE
33# include "errors.h"
34#else
bb1f44ab 35# include "rtlhash.h"
0b205f4c 36# include "diagnostic-core.h"
690abe5d 37#endif
759bebca 38
759bebca 39\f
40/* Indexed by rtx code, gives number of operands for an rtx with that code.
0e3985ee 41 Does NOT include rtx header data (code and links). */
759bebca 42
0e3985ee 43#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) sizeof FORMAT - 1 ,
44
1af5f160 45const unsigned char rtx_length[NUM_RTX_CODE] = {
0e3985ee 46#include "rtl.def"
47};
48
49#undef DEF_RTL_EXPR
759bebca 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
1af5f160 55const char * const rtx_name[NUM_RTX_CODE] = {
759bebca 56#include "rtl.def" /* rtl expressions are documented here */
57};
58
59#undef DEF_RTL_EXPR
60
759bebca 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
4bbea254 63 each character describes one operand. */
759bebca 64
1af5f160 65const char * const rtx_format[NUM_RTX_CODE] = {
759bebca 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'
d3115c90 73 "w" an integer of width HOST_BITS_PER_WIDE_INT
74 prints the integer
759bebca 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
aa4c562d 79 "T" like "s", but treated specially by the RTL reader;
80 only found in machine description patterns.
759bebca 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
a3426c4c 88 prints the uid of the insn.
89 "b" is a pointer to a bitmap header.
c849df63 90 "B" is a basic block pointer.
15183fd2 91 "t" is a tree pointer.
9edf7ea8 92 "r" a register.
93 "p" is a poly_uint16 offset. */
759bebca 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
6720e96c 103const enum rtx_class rtx_class[NUM_RTX_CODE] = {
f220c8f0 104#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
759bebca 105#include "rtl.def" /* rtl expressions are defined here */
106#undef DEF_RTL_EXPR
107};
108
93bb6f9c 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
bf6b5685 121/* Indexed by rtx code, gives the size of the rtx in bytes. */
122
f2d0e9f1 123const unsigned char rtx_code_size[NUM_RTX_CODE] = {
bf6b5685 124#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \
93bb6f9c 125 (RTX_CODE_HWINT_P (ENUM) \
bf6b5685 126 ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \
15183fd2 127 : (ENUM) == REG \
128 ? RTX_HDR_SIZE + sizeof (reg_info) \
bf6b5685 129 : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
130
131#include "rtl.def"
132#undef DEF_RTL_EXPR
133};
134
759bebca 135/* Names for kinds of NOTEs and REG_NOTEs. */
136
ad4583d9 137const char * const note_insn_name[NOTE_INSN_MAX] =
f220c8f0 138{
30f4db0d 139#define DEF_INSN_NOTE(NAME) #NAME,
140#include "insn-notes.def"
141#undef DEF_INSN_NOTE
f220c8f0 142};
143
30f4db0d 144const char * const reg_note_name[REG_NOTE_MAX] =
f220c8f0 145{
30f4db0d 146#define DEF_REG_NOTE(NAME) #NAME,
147#include "reg-notes.def"
148#undef DEF_REG_NOTE
f220c8f0 149};
759bebca 150
7a413494 151static size_t rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
152static size_t rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
153static size_t rtvec_alloc_counts;
154static size_t rtvec_alloc_sizes;
86736f9e 155
ad87de1e 156\f
759bebca 157/* Allocate an rtx vector of N elements.
158 Store the length, and initialize all elements to zero. */
159
160rtvec
3ad4992f 161rtvec_alloc (int n)
759bebca 162{
163 rtvec rt;
f220c8f0 164
ba72912a 165 rt = ggc_alloc_rtvec_sized (n);
aab2cf92 166 /* Clear out the vector. */
791ceafe 167 memset (&rt->elem[0], 0, n * sizeof (rtx));
759bebca 168
53d3f913 169 PUT_NUM_ELEM (rt, n);
86736f9e 170
ecd52ea9 171 if (GATHER_STATISTICS)
172 {
173 rtvec_alloc_counts++;
174 rtvec_alloc_sizes += n * sizeof (rtx);
175 }
86736f9e 176
759bebca 177 return rt;
178}
179
b447ca78 180/* Create a bitwise copy of VEC. */
181
182rtvec
183shallow_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
f2d0e9f1 194/* Return the number of bytes occupied by rtx value X. */
195
196unsigned int
dd9b9fc5 197rtx_size (const_rtx x)
f2d0e9f1 198{
e913b5cd 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)));
bbad7cd0 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 ());
6617cbc1 208 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
f2d0e9f1 209 return RTX_HDR_SIZE + sizeof (struct block_symbol);
210 return RTX_CODE_SIZE (GET_CODE (x));
211}
212
e913b5cd 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. */
759bebca 215
216rtx
e913b5cd 217rtx_alloc_stat_v (RTX_CODE code MEM_STAT_DECL, int extra)
759bebca 218{
e913b5cd 219 rtx rt = ggc_alloc_rtx_def_stat (RTX_CODE_SIZE (code) + extra
220 PASS_MEM_STAT);
1bfd55c5 221
791ceafe 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. */
b56b76ec 225
bf6b5685 226 memset (rt, 0, RTX_HDR_SIZE);
759bebca 227 PUT_CODE (rt, code);
86736f9e 228
ecd52ea9 229 if (GATHER_STATISTICS)
230 {
231 rtx_alloc_counts[code]++;
232 rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
233 }
86736f9e 234
759bebca 235 return rt;
236}
c49a29c7 237
e913b5cd 238/* Allocate an rtx of code CODE. The CODE is stored in the rtx;
239 all the rest is initialized to zero. */
240
241rtx
68095389 242rtx_alloc (RTX_CODE code MEM_STAT_DECL)
e913b5cd 243{
244 return rtx_alloc_stat_v (code PASS_MEM_STAT, 0);
245}
246
05c25ee6 247/* Write the wide constant X to OUTFILE. */
e913b5cd 248
249void
05c25ee6 250cwi_output_hex (FILE *outfile, const_rtx x)
e913b5cd 251{
05c25ee6 252 int i = CWI_GET_NUM_ELEM (x);
e913b5cd 253 gcc_assert (i > 0);
b3fba3cd 254 if (CWI_ELT (x, i - 1) == 0)
cc69d08a 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. */
e913b5cd 257 fprintf (outfile, "0x");
05c25ee6 258 fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i));
e913b5cd 259 while (--i >= 0)
05c25ee6 260 fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i));
e913b5cd 261}
262
759bebca 263\f
3072d30e 264/* Return true if ORIG is a sharable CONST. */
265
266bool
dd9b9fc5 267shared_const_p (const_rtx orig)
3072d30e 268{
269 gcc_assert (GET_CODE (orig) == CONST);
48e1416a 270
3072d30e 271 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
272 a LABEL_REF, it isn't sharable. */
bbad7cd0 273 poly_int64 offset;
3072d30e 274 return (GET_CODE (XEXP (orig, 0)) == PLUS
275 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
bbad7cd0 276 && poly_int_rtx_p (XEXP (XEXP (orig, 0), 1), &offset));
3072d30e 277}
278
279
759bebca 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
284rtx
3ad4992f 285copy_rtx (rtx orig)
759bebca 286{
19cb6b50 287 rtx copy;
288 int i, j;
289 RTX_CODE code;
290 const char *format_ptr;
759bebca 291
292 code = GET_CODE (orig);
293
294 switch (code)
295 {
296 case REG:
688ff29b 297 case DEBUG_EXPR:
298 case VALUE:
0349edce 299 CASE_CONST_ANY:
759bebca 300 case SYMBOL_REF:
301 case CODE_LABEL:
302 case PC:
303 case CC0:
1a860023 304 case RETURN:
9cb2517e 305 case SIMPLE_RETURN:
42e57659 306 case SCRATCH:
a92771b8 307 /* SCRATCH must be shared because they represent distinct values. */
759bebca 308 return orig;
c09425a0 309 case CLOBBER:
b291008a 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)))
c09425a0 315 return orig;
316 break;
42e57659 317
70bdfe23 318 case CLOBBER_HIGH:
319 gcc_assert (REG_P (XEXP (orig, 0)));
320 return orig;
321
42e57659 322 case CONST:
3072d30e 323 if (shared_const_p (orig))
42e57659 324 return orig;
325 break;
326
b4495254 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. */
0dbd1c74 331
332 default:
333 break;
759bebca 334 }
335
f2d0e9f1 336 /* Copy the various flags, fields, and other information. We assume
337 that all fields need copying, and then clear the fields that should
59241190 338 not be copied. That is the sensible default behavior, and forces
339 us to explicitly document why we are *not* copying a flag. */
f2d0e9f1 340 copy = shallow_copy_rtx (orig);
59241190 341
759bebca 342 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
343
344 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
f2d0e9f1 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':
9edf7ea8 365 case 'p':
f2d0e9f1 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 }
759bebca 378 return copy;
759bebca 379}
57ff0c05 380
381/* Create a new copy of an rtx. Only copy just one level. */
2a631e19 382
57ff0c05 383rtx
3523e41a 384shallow_copy_rtx (const_rtx orig MEM_STAT_DECL)
57ff0c05 385{
dd9b9fc5 386 const unsigned int size = rtx_size (orig);
5cc13354 387 rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT);
99f9d410 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;
57ff0c05 411}
759bebca 412\f
316bc009 413/* Nonzero when we are generating CONCATs. */
414int generating_concat_p;
723c0ee7 415
416/* Nonzero when we are expanding trees to RTL. */
417int currently_expanding_to_rtl;
418
140cb7e4 419\f
e1ab7874 420
48e1416a 421/* Same as rtx_equal_p, but call CB on each pair of rtx if CB is not NULL.
331cf53a 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. */
140cb7e4 425
426int
e1ab7874 427rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
140cb7e4 428{
19cb6b50 429 int i;
430 int j;
431 enum rtx_code code;
432 const char *fmt;
e1ab7874 433 rtx nx, ny;
140cb7e4 434
435 if (x == y)
436 return 1;
437 if (x == 0 || y == 0)
438 return 0;
439
e1ab7874 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
140cb7e4 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
04ec15fa 456 /* MEMs referring to different address space are not equivalent. */
bd1a81f7 457 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
458 return 0;
459
73f5c1e3 460 /* Some RTL can be compared nonrecursively. */
461 switch (code)
462 {
463 case REG:
011e6b51 464 return (REGNO (x) == REGNO (y));
73f5c1e3 465
466 case LABEL_REF:
c7799456 467 return label_ref_label (x) == label_ref_label (y);
73f5c1e3 468
469 case SYMBOL_REF:
470 return XSTR (x, 0) == XSTR (y, 0);
471
688ff29b 472 case DEBUG_EXPR:
9845d120 473 case VALUE:
73f5c1e3 474 case SCRATCH:
0349edce 475 CASE_CONST_UNIQUE:
73f5c1e3 476 return 0;
477
f9c61ef7 478 case DEBUG_IMPLICIT_PTR:
479 return DEBUG_IMPLICIT_PTR_DECL (x)
480 == DEBUG_IMPLICIT_PTR_DECL (y);
481
841424cc 482 case DEBUG_PARAMETER_REF:
483 return DEBUG_PARAMETER_REF_DECL (x)
643a814a 484 == DEBUG_PARAMETER_REF_DECL (y);
841424cc 485
a5701bde 486 case ENTRY_VALUE:
487 return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
488
73f5c1e3 489 default:
490 break;
491 }
140cb7e4 492
493 /* Compare the elements. If any pair of corresponding elements
e487406e 494 fail to match, return 0 for the whole thing. */
140cb7e4 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;
3a54beaf 505
140cb7e4 506 case 'n':
507 case 'i':
508 if (XINT (x, i) != XINT (y, i))
6675c1b7 509 {
510#ifndef GENERATOR_FILE
511 if (((code == ASM_OPERANDS && i == 6)
512 || (code == ASM_INPUT && i == 1))
5169661d 513 && XINT (x, i) == XINT (y, i))
6675c1b7 514 break;
515#endif
516 return 0;
517 }
140cb7e4 518 break;
519
9edf7ea8 520 case 'p':
521 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
522 return 0;
523 break;
524
140cb7e4 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++)
48e1416a 533 if (rtx_equal_p_cb (XVECEXP (x, i, j),
e1ab7874 534 XVECEXP (y, i, j), cb) == 0)
140cb7e4 535 return 0;
536 break;
537
538 case 'e':
e1ab7874 539 if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0)
140cb7e4 540 return 0;
541 break;
542
543 case 'S':
544 case 's':
100e94da 545 if ((XSTR (x, i) || XSTR (y, i))
546 && (! XSTR (x, i) || ! XSTR (y, i)
547 || strcmp (XSTR (x, i), XSTR (y, i))))
140cb7e4 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:
04e579b6 563 gcc_unreachable ();
140cb7e4 564 }
565 }
566 return 1;
567}
86736f9e 568
e1ab7874 569/* Return 1 if X and Y are identical-looking rtx's.
331cf53a 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. */
e1ab7874 573
574int
575rtx_equal_p (const_rtx x, const_rtx y)
576{
331cf53a 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
04ec15fa 598 /* MEMs referring to different address space are not equivalent. */
bd1a81f7 599 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
600 return 0;
601
331cf53a 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:
c7799456 609 return label_ref_label (x) == label_ref_label (y);
331cf53a 610
611 case SYMBOL_REF:
612 return XSTR (x, 0) == XSTR (y, 0);
613
688ff29b 614 case DEBUG_EXPR:
9845d120 615 case VALUE:
331cf53a 616 case SCRATCH:
0349edce 617 CASE_CONST_UNIQUE:
331cf53a 618 return 0;
619
f9c61ef7 620 case DEBUG_IMPLICIT_PTR:
621 return DEBUG_IMPLICIT_PTR_DECL (x)
622 == DEBUG_IMPLICIT_PTR_DECL (y);
623
841424cc 624 case DEBUG_PARAMETER_REF:
625 return DEBUG_PARAMETER_REF_DECL (x)
626 == DEBUG_PARAMETER_REF_DECL (y);
627
a5701bde 628 case ENTRY_VALUE:
629 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
630
331cf53a 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))
6675c1b7 651 {
652#ifndef GENERATOR_FILE
653 if (((code == ASM_OPERANDS && i == 6)
654 || (code == ASM_INPUT && i == 1))
5169661d 655 && XINT (x, i) == XINT (y, i))
6675c1b7 656 break;
657#endif
658 return 0;
659 }
331cf53a 660 break;
661
9edf7ea8 662 case 'p':
663 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
664 return 0;
665 break;
666
331cf53a 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;
e1ab7874 708}
709
62fdb8e4 710/* Return true if all elements of VEC are equal. */
711
712bool
713rtvec_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
03acb861 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
740enum rtx_code
741classify_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;
10a13d5e 761 bool has_return_p = false;
03acb861 762 for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
763 if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
764 return CALL_INSN;
d987e663 765 else if (ANY_RETURN_P (XVECEXP (x, 0, j)))
10a13d5e 766 has_return_p = true;
03acb861 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;
10a13d5e 773 if (has_return_p)
774 return JUMP_INSN;
03acb861 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
7a413494 788/* Comparator of indices based on rtx_alloc_counts. */
789
790static int
791rtx_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
2e2fd8fe 799void
800dump_rtx_statistics (void)
86736f9e 801{
86736f9e 802 int total_counts = 0;
803 int total_sizes = 0;
ecd52ea9 804
805 if (! GATHER_STATISTICS)
806 {
807 fprintf (stderr, "No RTX statistics\n");
808 return;
809 }
810
7a413494 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 {
03fac02c 824 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
7a413494 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
86736f9e 833 if (rtvec_alloc_counts)
834 {
03fac02c 835 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", "rtvec",
7a413494 836 SIZE_AMOUNT (rtvec_alloc_counts),
837 SIZE_AMOUNT (rtvec_alloc_sizes));
86736f9e 838 total_counts += rtvec_alloc_counts;
839 total_sizes += rtvec_alloc_sizes;
840 }
7a413494 841 fprintf (stderr, "-----------------------------------------------\n");
03fac02c 842 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n",
7a413494 843 "Total", SIZE_AMOUNT (total_counts),
844 SIZE_AMOUNT (total_sizes));
845 fprintf (stderr, "-----------------------------------------------\n");
86736f9e 846}
140cb7e4 847\f
0c4e40c5 848#if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
25999090 849void
dd9b9fc5 850rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line,
3ad4992f 851 const char *func)
25999090 852{
0fc48b82 853 internal_error
1e5fcbe2 854 ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
0fc48b82 855 n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
856 func, trim_filename (file), line);
25999090 857}
858
859void
dd9b9fc5 860rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line,
3ad4992f 861 const char *func)
25999090 862{
0fc48b82 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);
25999090 867}
868
869void
dd9b9fc5 870rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file,
3ad4992f 871 int line, const char *func)
25999090 872{
0fc48b82 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);
25999090 877}
878
005d995b 879void
dd9b9fc5 880rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file,
3ad4992f 881 int line, const char *func)
005d995b 882{
1e5fcbe2 883 internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
0fc48b82 884 GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
885 trim_filename (file), line);
005d995b 886}
887
888void
dd9b9fc5 889rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
3ad4992f 890 const char *file, int line, const char *func)
005d995b 891{
0fc48b82 892 internal_error
1e5fcbe2 893 ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
0fc48b82 894 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
a194077b 895 func, trim_filename (file), line);
005d995b 896}
897
34b780a6 898void
899rtl_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
e8aaae4e 909void
3754d046 910rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
e8aaae4e 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
f2d0e9f1 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
927void
928rtl_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
e913b5cd 935/* XXX Maybe print the vector? */
936void
05c25ee6 937cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line,
938 const char *func)
e913b5cd 939{
940 internal_error
941 ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d",
05c25ee6 942 n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line);
e913b5cd 943}
944
25999090 945/* XXX Maybe print the vector? */
946void
dd9b9fc5 947rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line,
3ad4992f 948 const char *func)
25999090 949{
0fc48b82 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);
25999090 953}
0c4e40c5 954#endif /* ENABLE_RTL_CHECKING */
e7f75e15 955
956#if defined ENABLE_RTL_FLAG_CHECKING
957void
dd9b9fc5 958rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
3ad4992f 959 int line, const char *func)
e7f75e15 960{
961 internal_error
1e5fcbe2 962 ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
3c6858c6 963 name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
e7f75e15 964}
965#endif /* ENABLE_RTL_FLAG_CHECKING */