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