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