Mercurial > hg > CbC > CbC_gcc
comparison gcc/rtl.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* RTL utility routines. | 1 /* RTL utility routines. |
2 Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002, | 2 Copyright (C) 1987-2017 Free Software Foundation, Inc. |
3 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | |
4 Free Software Foundation, Inc. | |
5 | 3 |
6 This file is part of GCC. | 4 This file is part of GCC. |
7 | 5 |
8 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
9 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
29 | 27 |
30 #include "system.h" | 28 #include "system.h" |
31 #include "coretypes.h" | 29 #include "coretypes.h" |
32 #include "tm.h" | 30 #include "tm.h" |
33 #include "rtl.h" | 31 #include "rtl.h" |
34 #include "ggc.h" | |
35 #ifdef GENERATOR_FILE | 32 #ifdef GENERATOR_FILE |
36 # include "errors.h" | 33 # include "errors.h" |
37 #else | 34 #else |
35 # include "rtlhash.h" | |
38 # include "diagnostic-core.h" | 36 # include "diagnostic-core.h" |
39 #endif | 37 #endif |
40 | 38 |
41 | 39 |
42 /* Indexed by rtx code, gives number of operands for an rtx with that code. | 40 /* Indexed by rtx code, gives number of operands for an rtx with that code. |
88 the containing rtx may end before this operand | 86 the containing rtx may end before this operand |
89 "u" a pointer to another insn | 87 "u" a pointer to another insn |
90 prints the uid of the insn. | 88 prints the uid of the insn. |
91 "b" is a pointer to a bitmap header. | 89 "b" is a pointer to a bitmap header. |
92 "B" is a basic block pointer. | 90 "B" is a basic block pointer. |
93 "t" is a tree pointer. */ | 91 "t" is a tree pointer. |
92 "r" a register. */ | |
94 | 93 |
95 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , | 94 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , |
96 #include "rtl.def" /* rtl expressions are defined here */ | 95 #include "rtl.def" /* rtl expressions are defined here */ |
97 #undef DEF_RTL_EXPR | 96 #undef DEF_RTL_EXPR |
98 }; | 97 }; |
108 | 107 |
109 /* Indexed by rtx code, gives the size of the rtx in bytes. */ | 108 /* Indexed by rtx code, gives the size of the rtx in bytes. */ |
110 | 109 |
111 const unsigned char rtx_code_size[NUM_RTX_CODE] = { | 110 const unsigned char rtx_code_size[NUM_RTX_CODE] = { |
112 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \ | 111 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \ |
113 ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE || (ENUM) == CONST_FIXED\ | 112 (((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \ |
113 || (ENUM) == CONST_FIXED || (ENUM) == CONST_WIDE_INT) \ | |
114 ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \ | 114 ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \ |
115 : (ENUM) == REG \ | |
116 ? RTX_HDR_SIZE + sizeof (reg_info) \ | |
115 : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)), | 117 : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)), |
116 | 118 |
117 #include "rtl.def" | 119 #include "rtl.def" |
118 #undef DEF_RTL_EXPR | 120 #undef DEF_RTL_EXPR |
119 }; | 121 }; |
132 #define DEF_REG_NOTE(NAME) #NAME, | 134 #define DEF_REG_NOTE(NAME) #NAME, |
133 #include "reg-notes.def" | 135 #include "reg-notes.def" |
134 #undef DEF_REG_NOTE | 136 #undef DEF_REG_NOTE |
135 }; | 137 }; |
136 | 138 |
137 #ifdef GATHER_STATISTICS | |
138 static int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE]; | 139 static int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE]; |
139 static int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE]; | 140 static int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE]; |
140 static int rtvec_alloc_counts; | 141 static int rtvec_alloc_counts; |
141 static int rtvec_alloc_sizes; | 142 static int rtvec_alloc_sizes; |
142 #endif | |
143 | 143 |
144 | 144 |
145 /* Allocate an rtx vector of N elements. | 145 /* Allocate an rtx vector of N elements. |
146 Store the length, and initialize all elements to zero. */ | 146 Store the length, and initialize all elements to zero. */ |
147 | 147 |
154 /* Clear out the vector. */ | 154 /* Clear out the vector. */ |
155 memset (&rt->elem[0], 0, n * sizeof (rtx)); | 155 memset (&rt->elem[0], 0, n * sizeof (rtx)); |
156 | 156 |
157 PUT_NUM_ELEM (rt, n); | 157 PUT_NUM_ELEM (rt, n); |
158 | 158 |
159 #ifdef GATHER_STATISTICS | 159 if (GATHER_STATISTICS) |
160 rtvec_alloc_counts++; | 160 { |
161 rtvec_alloc_sizes += n * sizeof (rtx); | 161 rtvec_alloc_counts++; |
162 #endif | 162 rtvec_alloc_sizes += n * sizeof (rtx); |
163 } | |
163 | 164 |
164 return rt; | 165 return rt; |
165 } | 166 } |
166 | 167 |
167 /* Create a bitwise copy of VEC. */ | 168 /* Create a bitwise copy of VEC. */ |
181 /* Return the number of bytes occupied by rtx value X. */ | 182 /* Return the number of bytes occupied by rtx value X. */ |
182 | 183 |
183 unsigned int | 184 unsigned int |
184 rtx_size (const_rtx x) | 185 rtx_size (const_rtx x) |
185 { | 186 { |
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))); | |
186 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x)) | 192 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x)) |
187 return RTX_HDR_SIZE + sizeof (struct block_symbol); | 193 return RTX_HDR_SIZE + sizeof (struct block_symbol); |
188 return RTX_CODE_SIZE (GET_CODE (x)); | 194 return RTX_CODE_SIZE (GET_CODE (x)); |
189 } | 195 } |
190 | 196 |
191 /* Allocate an rtx of code CODE. The CODE is stored in the rtx; | 197 /* Allocate an rtx of code CODE with EXTRA bytes in it. The CODE is |
192 all the rest is initialized to zero. */ | 198 stored in the rtx; all the rest is initialized to zero. */ |
193 | 199 |
194 rtx | 200 rtx |
195 rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL) | 201 rtx_alloc_stat_v (RTX_CODE code MEM_STAT_DECL, int extra) |
196 { | 202 { |
197 rtx rt = ggc_alloc_zone_rtx_def_stat (&rtl_zone, RTX_CODE_SIZE (code) | 203 rtx rt = ggc_alloc_rtx_def_stat (RTX_CODE_SIZE (code) + extra |
198 PASS_MEM_STAT); | 204 PASS_MEM_STAT); |
199 | 205 |
200 /* We want to clear everything up to the FLD array. Normally, this | 206 /* We want to clear everything up to the FLD array. Normally, this |
201 is one int, but we don't want to assume that and it isn't very | 207 is one int, but we don't want to assume that and it isn't very |
202 portable anyway; this is. */ | 208 portable anyway; this is. */ |
203 | 209 |
204 memset (rt, 0, RTX_HDR_SIZE); | 210 memset (rt, 0, RTX_HDR_SIZE); |
205 PUT_CODE (rt, code); | 211 PUT_CODE (rt, code); |
206 | 212 |
207 #ifdef GATHER_STATISTICS | 213 if (GATHER_STATISTICS) |
208 rtx_alloc_counts[code]++; | 214 { |
209 rtx_alloc_sizes[code] += RTX_CODE_SIZE (code); | 215 rtx_alloc_counts[code]++; |
210 #endif | 216 rtx_alloc_sizes[code] += RTX_CODE_SIZE (code); |
217 } | |
211 | 218 |
212 return rt; | 219 return rt; |
220 } | |
221 | |
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 | |
226 rtx_alloc (RTX_CODE code MEM_STAT_DECL) | |
227 { | |
228 return rtx_alloc_stat_v (code PASS_MEM_STAT, 0); | |
229 } | |
230 | |
231 /* Write the wide constant X to OUTFILE. */ | |
232 | |
233 void | |
234 cwi_output_hex (FILE *outfile, const_rtx x) | |
235 { | |
236 int i = CWI_GET_NUM_ELEM (x); | |
237 gcc_assert (i > 0); | |
238 if (CWI_ELT (x, i - 1) == 0) | |
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. */ | |
241 fprintf (outfile, "0x"); | |
242 fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i)); | |
243 while (--i >= 0) | |
244 fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i)); | |
213 } | 245 } |
214 | 246 |
215 | 247 |
216 /* Return true if ORIG is a sharable CONST. */ | 248 /* Return true if ORIG is a sharable CONST. */ |
217 | 249 |
222 | 254 |
223 /* CONST can be shared if it contains a SYMBOL_REF. If it contains | 255 /* CONST can be shared if it contains a SYMBOL_REF. If it contains |
224 a LABEL_REF, it isn't sharable. */ | 256 a LABEL_REF, it isn't sharable. */ |
225 return (GET_CODE (XEXP (orig, 0)) == PLUS | 257 return (GET_CODE (XEXP (orig, 0)) == PLUS |
226 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF | 258 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF |
227 && CONST_INT_P(XEXP (XEXP (orig, 0), 1))); | 259 && CONST_INT_P (XEXP (XEXP (orig, 0), 1))); |
228 } | 260 } |
229 | 261 |
230 | 262 |
231 /* Create a new copy of an rtx. | 263 /* Create a new copy of an rtx. |
232 Recursively copies the operands of the rtx, | 264 Recursively copies the operands of the rtx, |
245 switch (code) | 277 switch (code) |
246 { | 278 { |
247 case REG: | 279 case REG: |
248 case DEBUG_EXPR: | 280 case DEBUG_EXPR: |
249 case VALUE: | 281 case VALUE: |
250 case CONST_INT: | 282 CASE_CONST_ANY: |
251 case CONST_DOUBLE: | |
252 case CONST_FIXED: | |
253 case CONST_VECTOR: | |
254 case SYMBOL_REF: | 283 case SYMBOL_REF: |
255 case CODE_LABEL: | 284 case CODE_LABEL: |
256 case PC: | 285 case PC: |
257 case CC0: | 286 case CC0: |
287 case RETURN: | |
288 case SIMPLE_RETURN: | |
258 case SCRATCH: | 289 case SCRATCH: |
259 /* SCRATCH must be shared because they represent distinct values. */ | 290 /* SCRATCH must be shared because they represent distinct values. */ |
260 return orig; | 291 return orig; |
261 case CLOBBER: | 292 case CLOBBER: |
262 if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER) | 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))) | |
263 return orig; | 298 return orig; |
264 break; | 299 break; |
265 | 300 |
266 case CONST: | 301 case CONST: |
267 if (shared_const_p (orig)) | 302 if (shared_const_p (orig)) |
280 /* Copy the various flags, fields, and other information. We assume | 315 /* Copy the various flags, fields, and other information. We assume |
281 that all fields need copying, and then clear the fields that should | 316 that all fields need copying, and then clear the fields that should |
282 not be copied. That is the sensible default behavior, and forces | 317 not be copied. That is the sensible default behavior, and forces |
283 us to explicitly document why we are *not* copying a flag. */ | 318 us to explicitly document why we are *not* copying a flag. */ |
284 copy = shallow_copy_rtx (orig); | 319 copy = shallow_copy_rtx (orig); |
285 | |
286 /* We do not copy the USED flag, which is used as a mark bit during | |
287 walks over the RTL. */ | |
288 RTX_FLAG (copy, used) = 0; | |
289 | |
290 /* We do not copy FRAME_RELATED for INSNs. */ | |
291 if (INSN_P (orig)) | |
292 RTX_FLAG (copy, frame_related) = 0; | |
293 RTX_FLAG (copy, jump) = RTX_FLAG (orig, jump); | |
294 RTX_FLAG (copy, call) = RTX_FLAG (orig, call); | |
295 | 320 |
296 format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); | 321 format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); |
297 | 322 |
298 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) | 323 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) |
299 switch (*format_ptr++) | 324 switch (*format_ptr++) |
332 } | 357 } |
333 | 358 |
334 /* Create a new copy of an rtx. Only copy just one level. */ | 359 /* Create a new copy of an rtx. Only copy just one level. */ |
335 | 360 |
336 rtx | 361 rtx |
337 shallow_copy_rtx_stat (const_rtx orig MEM_STAT_DECL) | 362 shallow_copy_rtx (const_rtx orig MEM_STAT_DECL) |
338 { | 363 { |
339 const unsigned int size = rtx_size (orig); | 364 const unsigned int size = rtx_size (orig); |
340 rtx const copy = ggc_alloc_zone_rtx_def_stat (&rtl_zone, size PASS_MEM_STAT); | 365 rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT); |
341 return (rtx) memcpy (copy, orig, size); | 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; | |
342 } | 389 } |
343 | 390 |
344 /* Nonzero when we are generating CONCATs. */ | 391 /* Nonzero when we are generating CONCATs. */ |
345 int generating_concat_p; | 392 int generating_concat_p; |
346 | 393 |
382 (REG:SI x) and (REG:HI x) are NOT equivalent. */ | 429 (REG:SI x) and (REG:HI x) are NOT equivalent. */ |
383 | 430 |
384 if (GET_MODE (x) != GET_MODE (y)) | 431 if (GET_MODE (x) != GET_MODE (y)) |
385 return 0; | 432 return 0; |
386 | 433 |
387 /* MEMs refering to different address space are not equivalent. */ | 434 /* MEMs referring to different address space are not equivalent. */ |
388 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) | 435 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) |
389 return 0; | 436 return 0; |
390 | 437 |
391 /* Some RTL can be compared nonrecursively. */ | 438 /* Some RTL can be compared nonrecursively. */ |
392 switch (code) | 439 switch (code) |
393 { | 440 { |
394 case REG: | 441 case REG: |
395 return (REGNO (x) == REGNO (y)); | 442 return (REGNO (x) == REGNO (y)); |
396 | 443 |
397 case LABEL_REF: | 444 case LABEL_REF: |
398 return XEXP (x, 0) == XEXP (y, 0); | 445 return label_ref_label (x) == label_ref_label (y); |
399 | 446 |
400 case SYMBOL_REF: | 447 case SYMBOL_REF: |
401 return XSTR (x, 0) == XSTR (y, 0); | 448 return XSTR (x, 0) == XSTR (y, 0); |
402 | 449 |
403 case DEBUG_EXPR: | 450 case DEBUG_EXPR: |
404 case VALUE: | 451 case VALUE: |
405 case SCRATCH: | 452 case SCRATCH: |
406 case CONST_DOUBLE: | 453 CASE_CONST_UNIQUE: |
407 case CONST_INT: | |
408 case CONST_FIXED: | |
409 return 0; | 454 return 0; |
410 | 455 |
411 case DEBUG_IMPLICIT_PTR: | 456 case DEBUG_IMPLICIT_PTR: |
412 return DEBUG_IMPLICIT_PTR_DECL (x) | 457 return DEBUG_IMPLICIT_PTR_DECL (x) |
413 == DEBUG_IMPLICIT_PTR_DECL (y); | 458 == DEBUG_IMPLICIT_PTR_DECL (y); |
459 | |
460 case DEBUG_PARAMETER_REF: | |
461 return DEBUG_PARAMETER_REF_DECL (x) | |
462 == DEBUG_PARAMETER_REF_DECL (y); | |
463 | |
464 case ENTRY_VALUE: | |
465 return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb); | |
414 | 466 |
415 default: | 467 default: |
416 break; | 468 break; |
417 } | 469 } |
418 | 470 |
434 if (XINT (x, i) != XINT (y, i)) | 486 if (XINT (x, i) != XINT (y, i)) |
435 { | 487 { |
436 #ifndef GENERATOR_FILE | 488 #ifndef GENERATOR_FILE |
437 if (((code == ASM_OPERANDS && i == 6) | 489 if (((code == ASM_OPERANDS && i == 6) |
438 || (code == ASM_INPUT && i == 1)) | 490 || (code == ASM_INPUT && i == 1)) |
439 && locator_eq (XINT (x, i), XINT (y, i))) | 491 && XINT (x, i) == XINT (y, i)) |
440 break; | 492 break; |
441 #endif | 493 #endif |
442 return 0; | 494 return 0; |
443 } | 495 } |
444 break; | 496 break; |
514 (REG:SI x) and (REG:HI x) are NOT equivalent. */ | 566 (REG:SI x) and (REG:HI x) are NOT equivalent. */ |
515 | 567 |
516 if (GET_MODE (x) != GET_MODE (y)) | 568 if (GET_MODE (x) != GET_MODE (y)) |
517 return 0; | 569 return 0; |
518 | 570 |
519 /* MEMs refering to different address space are not equivalent. */ | 571 /* MEMs referring to different address space are not equivalent. */ |
520 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) | 572 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) |
521 return 0; | 573 return 0; |
522 | 574 |
523 /* Some RTL can be compared nonrecursively. */ | 575 /* Some RTL can be compared nonrecursively. */ |
524 switch (code) | 576 switch (code) |
525 { | 577 { |
526 case REG: | 578 case REG: |
527 return (REGNO (x) == REGNO (y)); | 579 return (REGNO (x) == REGNO (y)); |
528 | 580 |
529 case LABEL_REF: | 581 case LABEL_REF: |
530 return XEXP (x, 0) == XEXP (y, 0); | 582 return label_ref_label (x) == label_ref_label (y); |
531 | 583 |
532 case SYMBOL_REF: | 584 case SYMBOL_REF: |
533 return XSTR (x, 0) == XSTR (y, 0); | 585 return XSTR (x, 0) == XSTR (y, 0); |
534 | 586 |
535 case DEBUG_EXPR: | 587 case DEBUG_EXPR: |
536 case VALUE: | 588 case VALUE: |
537 case SCRATCH: | 589 case SCRATCH: |
538 case CONST_DOUBLE: | 590 CASE_CONST_UNIQUE: |
539 case CONST_INT: | |
540 case CONST_FIXED: | |
541 return 0; | 591 return 0; |
542 | 592 |
543 case DEBUG_IMPLICIT_PTR: | 593 case DEBUG_IMPLICIT_PTR: |
544 return DEBUG_IMPLICIT_PTR_DECL (x) | 594 return DEBUG_IMPLICIT_PTR_DECL (x) |
545 == DEBUG_IMPLICIT_PTR_DECL (y); | 595 == DEBUG_IMPLICIT_PTR_DECL (y); |
596 | |
597 case DEBUG_PARAMETER_REF: | |
598 return DEBUG_PARAMETER_REF_DECL (x) | |
599 == DEBUG_PARAMETER_REF_DECL (y); | |
600 | |
601 case ENTRY_VALUE: | |
602 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y)); | |
546 | 603 |
547 default: | 604 default: |
548 break; | 605 break; |
549 } | 606 } |
550 | 607 |
566 if (XINT (x, i) != XINT (y, i)) | 623 if (XINT (x, i) != XINT (y, i)) |
567 { | 624 { |
568 #ifndef GENERATOR_FILE | 625 #ifndef GENERATOR_FILE |
569 if (((code == ASM_OPERANDS && i == 6) | 626 if (((code == ASM_OPERANDS && i == 6) |
570 || (code == ASM_INPUT && i == 1)) | 627 || (code == ASM_INPUT && i == 1)) |
571 && locator_eq (XINT (x, i), XINT (y, i))) | 628 && XINT (x, i) == XINT (y, i)) |
572 break; | 629 break; |
573 #endif | 630 #endif |
574 return 0; | 631 return 0; |
575 } | 632 } |
576 break; | 633 break; |
616 } | 673 } |
617 } | 674 } |
618 return 1; | 675 return 1; |
619 } | 676 } |
620 | 677 |
621 /* Iteratively hash rtx X. */ | 678 /* Return true if all elements of VEC are equal. */ |
622 | 679 |
623 hashval_t | 680 bool |
624 iterative_hash_rtx (const_rtx x, hashval_t hash) | 681 rtvec_all_equal_p (const_rtvec vec) |
625 { | 682 { |
626 enum rtx_code code; | 683 const_rtx first = RTVEC_ELT (vec, 0); |
627 enum machine_mode mode; | 684 /* Optimize the important special case of a vector of constants. |
628 int i, j; | 685 The main use of this function is to detect whether every element |
629 const char *fmt; | 686 of CONST_VECTOR is the same. */ |
630 | 687 switch (GET_CODE (first)) |
631 if (x == NULL_RTX) | 688 { |
632 return hash; | 689 CASE_CONST_UNIQUE: |
633 code = GET_CODE (x); | 690 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i) |
634 hash = iterative_hash_object (code, hash); | 691 if (first != RTVEC_ELT (vec, i)) |
635 mode = GET_MODE (x); | 692 return false; |
636 hash = iterative_hash_object (mode, hash); | 693 return true; |
637 switch (code) | 694 |
638 { | |
639 case REG: | |
640 i = REGNO (x); | |
641 return iterative_hash_object (i, hash); | |
642 case CONST_INT: | |
643 return iterative_hash_object (INTVAL (x), hash); | |
644 case SYMBOL_REF: | |
645 if (XSTR (x, 0)) | |
646 return iterative_hash (XSTR (x, 0), strlen (XSTR (x, 0)) + 1, | |
647 hash); | |
648 return hash; | |
649 case LABEL_REF: | |
650 case DEBUG_EXPR: | |
651 case VALUE: | |
652 case SCRATCH: | |
653 case CONST_DOUBLE: | |
654 case CONST_FIXED: | |
655 case DEBUG_IMPLICIT_PTR: | |
656 return hash; | |
657 default: | 695 default: |
658 break; | 696 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i) |
659 } | 697 if (!rtx_equal_p (first, RTVEC_ELT (vec, i))) |
660 | 698 return false; |
661 fmt = GET_RTX_FORMAT (code); | 699 return true; |
662 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | 700 } |
663 switch (fmt[i]) | 701 } |
664 { | 702 |
665 case 'w': | 703 /* Return an indication of which type of insn should have X as a body. |
666 hash = iterative_hash_object (XWINT (x, i), hash); | 704 In generator files, this can be UNKNOWN if the answer is only known |
667 break; | 705 at (GCC) runtime. Otherwise the value is CODE_LABEL, INSN, CALL_INSN |
668 case 'n': | 706 or JUMP_INSN. */ |
669 case 'i': | 707 |
670 hash = iterative_hash_object (XINT (x, i), hash); | 708 enum rtx_code |
671 break; | 709 classify_insn (rtx x) |
672 case 'V': | 710 { |
673 case 'E': | 711 if (LABEL_P (x)) |
674 j = XVECLEN (x, i); | 712 return CODE_LABEL; |
675 hash = iterative_hash_object (j, hash); | 713 if (GET_CODE (x) == CALL) |
676 for (j = 0; j < XVECLEN (x, i); j++) | 714 return CALL_INSN; |
677 hash = iterative_hash_rtx (XVECEXP (x, i, j), hash); | 715 if (ANY_RETURN_P (x)) |
678 break; | 716 return JUMP_INSN; |
679 case 'e': | 717 if (GET_CODE (x) == SET) |
680 hash = iterative_hash_rtx (XEXP (x, i), hash); | 718 { |
681 break; | 719 if (GET_CODE (SET_DEST (x)) == PC) |
682 case 'S': | 720 return JUMP_INSN; |
683 case 's': | 721 else if (GET_CODE (SET_SRC (x)) == CALL) |
684 if (XSTR (x, i)) | 722 return CALL_INSN; |
685 hash = iterative_hash (XSTR (x, 0), strlen (XSTR (x, 0)) + 1, | 723 else |
686 hash); | 724 return INSN; |
687 break; | 725 } |
688 default: | 726 if (GET_CODE (x) == PARALLEL) |
689 break; | 727 { |
690 } | 728 int j; |
691 return hash; | 729 bool has_return_p = false; |
730 for (j = XVECLEN (x, 0) - 1; j >= 0; j--) | |
731 if (GET_CODE (XVECEXP (x, 0, j)) == CALL) | |
732 return CALL_INSN; | |
733 else if (ANY_RETURN_P (XVECEXP (x, 0, j))) | |
734 has_return_p = true; | |
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; | |
741 if (has_return_p) | |
742 return JUMP_INSN; | |
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; | |
692 } | 754 } |
693 | 755 |
694 void | 756 void |
695 dump_rtx_statistics (void) | 757 dump_rtx_statistics (void) |
696 { | 758 { |
697 #ifdef GATHER_STATISTICS | |
698 int i; | 759 int i; |
699 int total_counts = 0; | 760 int total_counts = 0; |
700 int total_sizes = 0; | 761 int total_sizes = 0; |
762 | |
763 if (! GATHER_STATISTICS) | |
764 { | |
765 fprintf (stderr, "No RTX statistics\n"); | |
766 return; | |
767 } | |
768 | |
701 fprintf (stderr, "\nRTX Kind Count Bytes\n"); | 769 fprintf (stderr, "\nRTX Kind Count Bytes\n"); |
702 fprintf (stderr, "---------------------------------------\n"); | 770 fprintf (stderr, "---------------------------------------\n"); |
703 for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++) | 771 for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++) |
704 if (rtx_alloc_counts[i]) | 772 if (rtx_alloc_counts[i]) |
705 { | 773 { |
717 } | 785 } |
718 fprintf (stderr, "---------------------------------------\n"); | 786 fprintf (stderr, "---------------------------------------\n"); |
719 fprintf (stderr, "%-20s %7d %10d\n", | 787 fprintf (stderr, "%-20s %7d %10d\n", |
720 "Total", total_counts, total_sizes); | 788 "Total", total_counts, total_sizes); |
721 fprintf (stderr, "---------------------------------------\n"); | 789 fprintf (stderr, "---------------------------------------\n"); |
722 #endif | |
723 } | 790 } |
724 | 791 |
725 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) | 792 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) |
726 void | 793 void |
727 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line, | 794 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line, |
771 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)), | 838 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)), |
772 func, trim_filename (file), line); | 839 func, trim_filename (file), line); |
773 } | 840 } |
774 | 841 |
775 void | 842 void |
776 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, enum machine_mode mode, | 843 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode, |
777 bool not_mode, const char *file, int line, | 844 bool not_mode, const char *file, int line, |
778 const char *func) | 845 const char *func) |
779 { | 846 { |
780 internal_error ((not_mode | 847 internal_error ((not_mode |
781 ? ("RTL check: expected code '%s' and not mode '%s', " | 848 ? ("RTL check: expected code '%s' and not mode '%s', " |
798 "in %s, at %s:%d", func, trim_filename (file), line); | 865 "in %s, at %s:%d", func, trim_filename (file), line); |
799 } | 866 } |
800 | 867 |
801 /* XXX Maybe print the vector? */ | 868 /* XXX Maybe print the vector? */ |
802 void | 869 void |
870 cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line, | |
871 const char *func) | |
872 { | |
873 internal_error | |
874 ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d", | |
875 n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line); | |
876 } | |
877 | |
878 /* XXX Maybe print the vector? */ | |
879 void | |
803 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line, | 880 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line, |
804 const char *func) | 881 const char *func) |
805 { | 882 { |
806 internal_error | 883 internal_error |
807 ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d", | 884 ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d", |