Mercurial > hg > CbC > CbC_gcc
comparison gcc/cselib.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Common subexpression elimination library for GNU compiler. | 1 /* Common subexpression elimination library for GNU compiler. |
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | 2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
3 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | 3 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
31 #include "flags.h" | 31 #include "flags.h" |
32 #include "insn-config.h" | 32 #include "insn-config.h" |
33 #include "recog.h" | 33 #include "recog.h" |
34 #include "function.h" | 34 #include "function.h" |
35 #include "emit-rtl.h" | 35 #include "emit-rtl.h" |
36 #include "toplev.h" | 36 #include "diagnostic-core.h" |
37 #include "output.h" | 37 #include "output.h" |
38 #include "ggc.h" | 38 #include "ggc.h" |
39 #include "hashtab.h" | 39 #include "hashtab.h" |
40 #include "tree-pass.h" | 40 #include "tree-pass.h" |
41 #include "cselib.h" | 41 #include "cselib.h" |
42 #include "params.h" | 42 #include "params.h" |
43 #include "alloc-pool.h" | 43 #include "alloc-pool.h" |
44 #include "target.h" | 44 #include "target.h" |
45 #include "bitmap.h" | 45 #include "bitmap.h" |
46 | |
47 /* A list of cselib_val structures. */ | |
48 struct elt_list { | |
49 struct elt_list *next; | |
50 cselib_val *elt; | |
51 }; | |
46 | 52 |
47 static bool cselib_record_memory; | 53 static bool cselib_record_memory; |
48 static bool cselib_preserve_constants; | 54 static bool cselib_preserve_constants; |
49 static int entry_and_rtx_equal_p (const void *, const void *); | 55 static int entry_and_rtx_equal_p (const void *, const void *); |
50 static hashval_t get_value_hash (const void *); | 56 static hashval_t get_value_hash (const void *); |
54 static void unchain_one_elt_list (struct elt_list **); | 60 static void unchain_one_elt_list (struct elt_list **); |
55 static void unchain_one_elt_loc_list (struct elt_loc_list **); | 61 static void unchain_one_elt_loc_list (struct elt_loc_list **); |
56 static int discard_useless_locs (void **, void *); | 62 static int discard_useless_locs (void **, void *); |
57 static int discard_useless_values (void **, void *); | 63 static int discard_useless_values (void **, void *); |
58 static void remove_useless_values (void); | 64 static void remove_useless_values (void); |
59 static unsigned int cselib_hash_rtx (rtx, int); | 65 static int rtx_equal_for_cselib_1 (rtx, rtx, enum machine_mode); |
66 static unsigned int cselib_hash_rtx (rtx, int, enum machine_mode); | |
60 static cselib_val *new_cselib_val (unsigned int, enum machine_mode, rtx); | 67 static cselib_val *new_cselib_val (unsigned int, enum machine_mode, rtx); |
61 static void add_mem_for_addr (cselib_val *, cselib_val *, rtx); | 68 static void add_mem_for_addr (cselib_val *, cselib_val *, rtx); |
62 static cselib_val *cselib_lookup_mem (rtx, int); | 69 static cselib_val *cselib_lookup_mem (rtx, int); |
63 static void cselib_invalidate_regno (unsigned int, enum machine_mode); | 70 static void cselib_invalidate_regno (unsigned int, enum machine_mode); |
64 static void cselib_invalidate_mem (rtx); | 71 static void cselib_invalidate_mem (rtx); |
176 | 183 |
177 /* If non-NULL, value of the eliminated arg_pointer_rtx or frame_pointer_rtx | 184 /* If non-NULL, value of the eliminated arg_pointer_rtx or frame_pointer_rtx |
178 that is constant through the whole function and should never be | 185 that is constant through the whole function and should never be |
179 eliminated. */ | 186 eliminated. */ |
180 static cselib_val *cfa_base_preserved_val; | 187 static cselib_val *cfa_base_preserved_val; |
188 static unsigned int cfa_base_preserved_regno; | |
181 | 189 |
182 /* Used to list all values that contain memory reference. | 190 /* Used to list all values that contain memory reference. |
183 May or may not contain the useless values - the list is compacted | 191 May or may not contain the useless values - the list is compacted |
184 each time memory is invalidated. */ | 192 each time memory is invalidated. */ |
185 static cselib_val *first_containing_mem = &dummy_val; | 193 static cselib_val *first_containing_mem = &dummy_val; |
336 | 344 |
337 max_value_regs = 0; | 345 max_value_regs = 0; |
338 | 346 |
339 if (cfa_base_preserved_val) | 347 if (cfa_base_preserved_val) |
340 { | 348 { |
341 unsigned int regno = REGNO (cfa_base_preserved_val->locs->loc); | 349 unsigned int regno = cfa_base_preserved_regno; |
342 unsigned int new_used_regs = 0; | 350 unsigned int new_used_regs = 0; |
343 for (i = 0; i < n_used_regs; i++) | 351 for (i = 0; i < n_used_regs; i++) |
344 if (used_regs[i] == regno) | 352 if (used_regs[i] == regno) |
345 { | 353 { |
346 new_used_regs = 1; | 354 new_used_regs = 1; |
381 cselib_get_next_uid (void) | 389 cselib_get_next_uid (void) |
382 { | 390 { |
383 return next_uid; | 391 return next_uid; |
384 } | 392 } |
385 | 393 |
394 /* See the documentation of cselib_find_slot below. */ | |
395 static enum machine_mode find_slot_memmode; | |
396 | |
397 /* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE, | |
398 INSERTing if requested. When X is part of the address of a MEM, | |
399 MEMMODE should specify the mode of the MEM. While searching the | |
400 table, MEMMODE is held in FIND_SLOT_MEMMODE, so that autoinc RTXs | |
401 in X can be resolved. */ | |
402 | |
403 static void ** | |
404 cselib_find_slot (rtx x, hashval_t hash, enum insert_option insert, | |
405 enum machine_mode memmode) | |
406 { | |
407 void **slot; | |
408 find_slot_memmode = memmode; | |
409 slot = htab_find_slot_with_hash (cselib_hash_table, x, hash, insert); | |
410 find_slot_memmode = VOIDmode; | |
411 return slot; | |
412 } | |
413 | |
386 /* The equality test for our hash table. The first argument ENTRY is a table | 414 /* The equality test for our hash table. The first argument ENTRY is a table |
387 element (i.e. a cselib_val), while the second arg X is an rtx. We know | 415 element (i.e. a cselib_val), while the second arg X is an rtx. We know |
388 that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a | 416 that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a |
389 CONST of an appropriate mode. */ | 417 CONST of an appropriate mode. */ |
390 | 418 |
410 x = XEXP (x, 0); | 438 x = XEXP (x, 0); |
411 | 439 |
412 /* We don't guarantee that distinct rtx's have different hash values, | 440 /* We don't guarantee that distinct rtx's have different hash values, |
413 so we need to do a comparison. */ | 441 so we need to do a comparison. */ |
414 for (l = v->locs; l; l = l->next) | 442 for (l = v->locs; l; l = l->next) |
415 if (rtx_equal_for_cselib_p (l->loc, x)) | 443 if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode)) |
416 { | 444 { |
417 promote_debug_loc (l); | 445 promote_debug_loc (l); |
418 return 1; | 446 return 1; |
419 } | 447 } |
420 | 448 |
569 | 597 |
570 /* Arrange for a REG value to be assumed constant through the whole function, | 598 /* Arrange for a REG value to be assumed constant through the whole function, |
571 never invalidated and preserved across cselib_reset_table calls. */ | 599 never invalidated and preserved across cselib_reset_table calls. */ |
572 | 600 |
573 void | 601 void |
574 cselib_preserve_cfa_base_value (cselib_val *v) | 602 cselib_preserve_cfa_base_value (cselib_val *v, unsigned int regno) |
575 { | 603 { |
576 if (cselib_preserve_constants | 604 if (cselib_preserve_constants |
577 && v->locs | 605 && v->locs |
578 && REG_P (v->locs->loc)) | 606 && REG_P (v->locs->loc)) |
579 cfa_base_preserved_val = v; | 607 { |
608 cfa_base_preserved_val = v; | |
609 cfa_base_preserved_regno = regno; | |
610 } | |
580 } | 611 } |
581 | 612 |
582 /* Clean all non-constant expressions in the hash table, but retain | 613 /* Clean all non-constant expressions in the hash table, but retain |
583 their values. */ | 614 their values. */ |
584 | 615 |
619 our gathered information into account. */ | 650 our gathered information into account. */ |
620 | 651 |
621 int | 652 int |
622 rtx_equal_for_cselib_p (rtx x, rtx y) | 653 rtx_equal_for_cselib_p (rtx x, rtx y) |
623 { | 654 { |
655 return rtx_equal_for_cselib_1 (x, y, VOIDmode); | |
656 } | |
657 | |
658 /* If x is a PLUS or an autoinc operation, expand the operation, | |
659 storing the offset, if any, in *OFF. */ | |
660 | |
661 static rtx | |
662 autoinc_split (rtx x, rtx *off, enum machine_mode memmode) | |
663 { | |
664 switch (GET_CODE (x)) | |
665 { | |
666 case PLUS: | |
667 *off = XEXP (x, 1); | |
668 return XEXP (x, 0); | |
669 | |
670 case PRE_DEC: | |
671 if (memmode == VOIDmode) | |
672 return x; | |
673 | |
674 *off = GEN_INT (-GET_MODE_SIZE (memmode)); | |
675 return XEXP (x, 0); | |
676 break; | |
677 | |
678 case PRE_INC: | |
679 if (memmode == VOIDmode) | |
680 return x; | |
681 | |
682 *off = GEN_INT (GET_MODE_SIZE (memmode)); | |
683 return XEXP (x, 0); | |
684 | |
685 case PRE_MODIFY: | |
686 return XEXP (x, 1); | |
687 | |
688 case POST_DEC: | |
689 case POST_INC: | |
690 case POST_MODIFY: | |
691 return XEXP (x, 0); | |
692 | |
693 default: | |
694 return x; | |
695 } | |
696 } | |
697 | |
698 /* Return nonzero if we can prove that X and Y contain the same value, | |
699 taking our gathered information into account. MEMMODE holds the | |
700 mode of the enclosing MEM, if any, as required to deal with autoinc | |
701 addressing modes. If X and Y are not (known to be) part of | |
702 addresses, MEMMODE should be VOIDmode. */ | |
703 | |
704 static int | |
705 rtx_equal_for_cselib_1 (rtx x, rtx y, enum machine_mode memmode) | |
706 { | |
624 enum rtx_code code; | 707 enum rtx_code code; |
625 const char *fmt; | 708 const char *fmt; |
626 int i; | 709 int i; |
627 | 710 |
628 if (REG_P (x) || MEM_P (x)) | 711 if (REG_P (x) || MEM_P (x)) |
629 { | 712 { |
630 cselib_val *e = cselib_lookup (x, GET_MODE (x), 0); | 713 cselib_val *e = cselib_lookup (x, GET_MODE (x), 0, memmode); |
631 | 714 |
632 if (e) | 715 if (e) |
633 x = e->val_rtx; | 716 x = e->val_rtx; |
634 } | 717 } |
635 | 718 |
636 if (REG_P (y) || MEM_P (y)) | 719 if (REG_P (y) || MEM_P (y)) |
637 { | 720 { |
638 cselib_val *e = cselib_lookup (y, GET_MODE (y), 0); | 721 cselib_val *e = cselib_lookup (y, GET_MODE (y), 0, memmode); |
639 | 722 |
640 if (e) | 723 if (e) |
641 y = e->val_rtx; | 724 y = e->val_rtx; |
642 } | 725 } |
643 | 726 |
657 rtx t = l->loc; | 740 rtx t = l->loc; |
658 | 741 |
659 /* Avoid infinite recursion. */ | 742 /* Avoid infinite recursion. */ |
660 if (REG_P (t) || MEM_P (t)) | 743 if (REG_P (t) || MEM_P (t)) |
661 continue; | 744 continue; |
662 else if (rtx_equal_for_cselib_p (t, y)) | 745 else if (rtx_equal_for_cselib_1 (t, y, memmode)) |
663 return 1; | 746 return 1; |
664 } | 747 } |
665 | 748 |
666 return 0; | 749 return 0; |
667 } | 750 } |
675 { | 758 { |
676 rtx t = l->loc; | 759 rtx t = l->loc; |
677 | 760 |
678 if (REG_P (t) || MEM_P (t)) | 761 if (REG_P (t) || MEM_P (t)) |
679 continue; | 762 continue; |
680 else if (rtx_equal_for_cselib_p (x, t)) | 763 else if (rtx_equal_for_cselib_1 (x, t, memmode)) |
681 return 1; | 764 return 1; |
682 } | 765 } |
683 | 766 |
684 return 0; | 767 return 0; |
685 } | 768 } |
686 | 769 |
687 if (GET_CODE (x) != GET_CODE (y) || GET_MODE (x) != GET_MODE (y)) | 770 if (GET_MODE (x) != GET_MODE (y)) |
688 return 0; | 771 return 0; |
772 | |
773 if (GET_CODE (x) != GET_CODE (y)) | |
774 { | |
775 rtx xorig = x, yorig = y; | |
776 rtx xoff = NULL, yoff = NULL; | |
777 | |
778 x = autoinc_split (x, &xoff, memmode); | |
779 y = autoinc_split (y, &yoff, memmode); | |
780 | |
781 if (!xoff != !yoff) | |
782 return 0; | |
783 | |
784 if (xoff && !rtx_equal_for_cselib_1 (xoff, yoff, memmode)) | |
785 return 0; | |
786 | |
787 /* Don't recurse if nothing changed. */ | |
788 if (x != xorig || y != yorig) | |
789 return rtx_equal_for_cselib_1 (x, y, memmode); | |
790 | |
791 return 0; | |
792 } | |
689 | 793 |
690 /* These won't be handled correctly by the code below. */ | 794 /* These won't be handled correctly by the code below. */ |
691 switch (GET_CODE (x)) | 795 switch (GET_CODE (x)) |
692 { | 796 { |
693 case CONST_DOUBLE: | 797 case CONST_DOUBLE: |
694 case CONST_FIXED: | 798 case CONST_FIXED: |
695 case DEBUG_EXPR: | 799 case DEBUG_EXPR: |
696 return 0; | 800 return 0; |
697 | 801 |
802 case DEBUG_IMPLICIT_PTR: | |
803 return DEBUG_IMPLICIT_PTR_DECL (x) | |
804 == DEBUG_IMPLICIT_PTR_DECL (y); | |
805 | |
698 case LABEL_REF: | 806 case LABEL_REF: |
699 return XEXP (x, 0) == XEXP (y, 0); | 807 return XEXP (x, 0) == XEXP (y, 0); |
808 | |
809 case MEM: | |
810 /* We have to compare any autoinc operations in the addresses | |
811 using this MEM's mode. */ | |
812 return rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 0), GET_MODE (x)); | |
700 | 813 |
701 default: | 814 default: |
702 break; | 815 break; |
703 } | 816 } |
704 | 817 |
728 if (XVECLEN (x, i) != XVECLEN (y, i)) | 841 if (XVECLEN (x, i) != XVECLEN (y, i)) |
729 return 0; | 842 return 0; |
730 | 843 |
731 /* And the corresponding elements must match. */ | 844 /* And the corresponding elements must match. */ |
732 for (j = 0; j < XVECLEN (x, i); j++) | 845 for (j = 0; j < XVECLEN (x, i); j++) |
733 if (! rtx_equal_for_cselib_p (XVECEXP (x, i, j), | 846 if (! rtx_equal_for_cselib_1 (XVECEXP (x, i, j), |
734 XVECEXP (y, i, j))) | 847 XVECEXP (y, i, j), memmode)) |
735 return 0; | 848 return 0; |
736 break; | 849 break; |
737 | 850 |
738 case 'e': | 851 case 'e': |
739 if (i == 1 | 852 if (i == 1 |
740 && targetm.commutative_p (x, UNKNOWN) | 853 && targetm.commutative_p (x, UNKNOWN) |
741 && rtx_equal_for_cselib_p (XEXP (x, 1), XEXP (y, 0)) | 854 && rtx_equal_for_cselib_1 (XEXP (x, 1), XEXP (y, 0), memmode) |
742 && rtx_equal_for_cselib_p (XEXP (x, 0), XEXP (y, 1))) | 855 && rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 1), memmode)) |
743 return 1; | 856 return 1; |
744 if (! rtx_equal_for_cselib_p (XEXP (x, i), XEXP (y, i))) | 857 if (! rtx_equal_for_cselib_1 (XEXP (x, i), XEXP (y, i), memmode)) |
745 return 0; | 858 return 0; |
746 break; | 859 break; |
747 | 860 |
748 case 'S': | 861 case 'S': |
749 case 's': | 862 case 's': |
791 N.B. this hash function returns the same hash value for RTXes that | 904 N.B. this hash function returns the same hash value for RTXes that |
792 differ only in the order of operands, thus it is suitable for comparisons | 905 differ only in the order of operands, thus it is suitable for comparisons |
793 that take commutativity into account. | 906 that take commutativity into account. |
794 If we wanted to also support associative rules, we'd have to use a different | 907 If we wanted to also support associative rules, we'd have to use a different |
795 strategy to avoid returning spurious 0, e.g. return ~(~0U >> 1) . | 908 strategy to avoid returning spurious 0, e.g. return ~(~0U >> 1) . |
909 MEMMODE indicates the mode of an enclosing MEM, and it's only | |
910 used to compute autoinc values. | |
796 We used to have a MODE argument for hashing for CONST_INTs, but that | 911 We used to have a MODE argument for hashing for CONST_INTs, but that |
797 didn't make sense, since it caused spurious hash differences between | 912 didn't make sense, since it caused spurious hash differences between |
798 (set (reg:SI 1) (const_int)) | 913 (set (reg:SI 1) (const_int)) |
799 (plus:SI (reg:SI 2) (reg:SI 1)) | 914 (plus:SI (reg:SI 2) (reg:SI 1)) |
800 and | 915 and |
801 (plus:SI (reg:SI 2) (const_int)) | 916 (plus:SI (reg:SI 2) (const_int)) |
802 If the mode is important in any context, it must be checked specifically | 917 If the mode is important in any context, it must be checked specifically |
803 in a comparison anyway, since relying on hash differences is unsafe. */ | 918 in a comparison anyway, since relying on hash differences is unsafe. */ |
804 | 919 |
805 static unsigned int | 920 static unsigned int |
806 cselib_hash_rtx (rtx x, int create) | 921 cselib_hash_rtx (rtx x, int create, enum machine_mode memmode) |
807 { | 922 { |
808 cselib_val *e; | 923 cselib_val *e; |
809 int i, j; | 924 int i, j; |
810 enum rtx_code code; | 925 enum rtx_code code; |
811 const char *fmt; | 926 const char *fmt; |
816 | 931 |
817 switch (code) | 932 switch (code) |
818 { | 933 { |
819 case MEM: | 934 case MEM: |
820 case REG: | 935 case REG: |
821 e = cselib_lookup (x, GET_MODE (x), create); | 936 e = cselib_lookup (x, GET_MODE (x), create, memmode); |
822 if (! e) | 937 if (! e) |
823 return 0; | 938 return 0; |
824 | 939 |
825 return e->hash; | 940 return e->hash; |
826 | 941 |
827 case DEBUG_EXPR: | 942 case DEBUG_EXPR: |
828 hash += ((unsigned) DEBUG_EXPR << 7) | 943 hash += ((unsigned) DEBUG_EXPR << 7) |
829 + DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)); | 944 + DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)); |
830 return hash ? hash : (unsigned int) DEBUG_EXPR; | 945 return hash ? hash : (unsigned int) DEBUG_EXPR; |
946 | |
947 case DEBUG_IMPLICIT_PTR: | |
948 hash += ((unsigned) DEBUG_IMPLICIT_PTR << 7) | |
949 + DECL_UID (DEBUG_IMPLICIT_PTR_DECL (x)); | |
950 return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR; | |
831 | 951 |
832 case CONST_INT: | 952 case CONST_INT: |
833 hash += ((unsigned) CONST_INT << 7) + INTVAL (x); | 953 hash += ((unsigned) CONST_INT << 7) + INTVAL (x); |
834 return hash ? hash : (unsigned int) CONST_INT; | 954 return hash ? hash : (unsigned int) CONST_INT; |
835 | 955 |
857 units = CONST_VECTOR_NUNITS (x); | 977 units = CONST_VECTOR_NUNITS (x); |
858 | 978 |
859 for (i = 0; i < units; ++i) | 979 for (i = 0; i < units; ++i) |
860 { | 980 { |
861 elt = CONST_VECTOR_ELT (x, i); | 981 elt = CONST_VECTOR_ELT (x, i); |
862 hash += cselib_hash_rtx (elt, 0); | 982 hash += cselib_hash_rtx (elt, 0, memmode); |
863 } | 983 } |
864 | 984 |
865 return hash; | 985 return hash; |
866 } | 986 } |
867 | 987 |
890 return hash ? hash : (unsigned int) SYMBOL_REF; | 1010 return hash ? hash : (unsigned int) SYMBOL_REF; |
891 } | 1011 } |
892 | 1012 |
893 case PRE_DEC: | 1013 case PRE_DEC: |
894 case PRE_INC: | 1014 case PRE_INC: |
1015 /* We can't compute these without knowing the MEM mode. */ | |
1016 gcc_assert (memmode != VOIDmode); | |
1017 i = GET_MODE_SIZE (memmode); | |
1018 if (code == PRE_DEC) | |
1019 i = -i; | |
1020 /* Adjust the hash so that (mem:MEMMODE (pre_* (reg))) hashes | |
1021 like (mem:MEMMODE (plus (reg) (const_int I))). */ | |
1022 hash += (unsigned) PLUS - (unsigned)code | |
1023 + cselib_hash_rtx (XEXP (x, 0), create, memmode) | |
1024 + cselib_hash_rtx (GEN_INT (i), create, memmode); | |
1025 return hash ? hash : 1 + (unsigned) PLUS; | |
1026 | |
1027 case PRE_MODIFY: | |
1028 gcc_assert (memmode != VOIDmode); | |
1029 return cselib_hash_rtx (XEXP (x, 1), create, memmode); | |
1030 | |
895 case POST_DEC: | 1031 case POST_DEC: |
896 case POST_INC: | 1032 case POST_INC: |
897 case POST_MODIFY: | 1033 case POST_MODIFY: |
898 case PRE_MODIFY: | 1034 gcc_assert (memmode != VOIDmode); |
1035 return cselib_hash_rtx (XEXP (x, 0), create, memmode); | |
1036 | |
899 case PC: | 1037 case PC: |
900 case CC0: | 1038 case CC0: |
901 case CALL: | 1039 case CALL: |
902 case UNSPEC_VOLATILE: | 1040 case UNSPEC_VOLATILE: |
903 return 0; | 1041 return 0; |
919 switch (fmt[i]) | 1057 switch (fmt[i]) |
920 { | 1058 { |
921 case 'e': | 1059 case 'e': |
922 { | 1060 { |
923 rtx tem = XEXP (x, i); | 1061 rtx tem = XEXP (x, i); |
924 unsigned int tem_hash = cselib_hash_rtx (tem, create); | 1062 unsigned int tem_hash = cselib_hash_rtx (tem, create, memmode); |
925 | 1063 |
926 if (tem_hash == 0) | 1064 if (tem_hash == 0) |
927 return 0; | 1065 return 0; |
928 | 1066 |
929 hash += tem_hash; | 1067 hash += tem_hash; |
931 break; | 1069 break; |
932 case 'E': | 1070 case 'E': |
933 for (j = 0; j < XVECLEN (x, i); j++) | 1071 for (j = 0; j < XVECLEN (x, i); j++) |
934 { | 1072 { |
935 unsigned int tem_hash | 1073 unsigned int tem_hash |
936 = cselib_hash_rtx (XVECEXP (x, i, j), create); | 1074 = cselib_hash_rtx (XVECEXP (x, i, j), create, memmode); |
937 | 1075 |
938 if (tem_hash == 0) | 1076 if (tem_hash == 0) |
939 return 0; | 1077 return 0; |
940 | 1078 |
941 hash += tem_hash; | 1079 hash += tem_hash; |
994 CSELIB_VAL_PTR (e->val_rtx) = e; | 1132 CSELIB_VAL_PTR (e->val_rtx) = e; |
995 e->addr_list = 0; | 1133 e->addr_list = 0; |
996 e->locs = 0; | 1134 e->locs = 0; |
997 e->next_containing_mem = 0; | 1135 e->next_containing_mem = 0; |
998 | 1136 |
999 if (dump_file && (dump_flags & TDF_DETAILS)) | 1137 if (dump_file && (dump_flags & TDF_CSELIB)) |
1000 { | 1138 { |
1001 fprintf (dump_file, "cselib value %u:%u ", e->uid, hash); | 1139 fprintf (dump_file, "cselib value %u:%u ", e->uid, hash); |
1002 if (flag_dump_noaddr || flag_dump_unnumbered) | 1140 if (flag_dump_noaddr || flag_dump_unnumbered) |
1003 fputs ("# ", dump_file); | 1141 fputs ("# ", dump_file); |
1004 else | 1142 else |
1044 | 1182 |
1045 static cselib_val * | 1183 static cselib_val * |
1046 cselib_lookup_mem (rtx x, int create) | 1184 cselib_lookup_mem (rtx x, int create) |
1047 { | 1185 { |
1048 enum machine_mode mode = GET_MODE (x); | 1186 enum machine_mode mode = GET_MODE (x); |
1187 enum machine_mode addr_mode; | |
1049 void **slot; | 1188 void **slot; |
1050 cselib_val *addr; | 1189 cselib_val *addr; |
1051 cselib_val *mem_elt; | 1190 cselib_val *mem_elt; |
1052 struct elt_list *l; | 1191 struct elt_list *l; |
1053 | 1192 |
1054 if (MEM_VOLATILE_P (x) || mode == BLKmode | 1193 if (MEM_VOLATILE_P (x) || mode == BLKmode |
1055 || !cselib_record_memory | 1194 || !cselib_record_memory |
1056 || (FLOAT_MODE_P (mode) && flag_float_store)) | 1195 || (FLOAT_MODE_P (mode) && flag_float_store)) |
1057 return 0; | 1196 return 0; |
1058 | 1197 |
1198 addr_mode = GET_MODE (XEXP (x, 0)); | |
1199 if (addr_mode == VOIDmode) | |
1200 addr_mode = Pmode; | |
1201 | |
1059 /* Look up the value for the address. */ | 1202 /* Look up the value for the address. */ |
1060 addr = cselib_lookup (XEXP (x, 0), mode, create); | 1203 addr = cselib_lookup (XEXP (x, 0), addr_mode, create, mode); |
1061 if (! addr) | 1204 if (! addr) |
1062 return 0; | 1205 return 0; |
1063 | 1206 |
1064 /* Find a value that describes a value of our mode at that address. */ | 1207 /* Find a value that describes a value of our mode at that address. */ |
1065 for (l = addr->addr_list; l; l = l->next) | 1208 for (l = addr->addr_list; l; l = l->next) |
1072 if (! create) | 1215 if (! create) |
1073 return 0; | 1216 return 0; |
1074 | 1217 |
1075 mem_elt = new_cselib_val (next_uid, mode, x); | 1218 mem_elt = new_cselib_val (next_uid, mode, x); |
1076 add_mem_for_addr (addr, mem_elt, x); | 1219 add_mem_for_addr (addr, mem_elt, x); |
1077 slot = htab_find_slot_with_hash (cselib_hash_table, wrap_constant (mode, x), | 1220 slot = cselib_find_slot (wrap_constant (mode, x), mem_elt->hash, |
1078 mem_elt->hash, INSERT); | 1221 INSERT, mode); |
1079 *slot = mem_elt; | 1222 *slot = mem_elt; |
1080 return mem_elt; | 1223 return mem_elt; |
1081 } | 1224 } |
1082 | 1225 |
1083 /* Search thru the possible substitutions in P. We prefer a non reg | 1226 /* Search thru the possible substitutions in P. We prefer a non reg |
1111 && CSELIB_VAL_PTR (p->loc)->locs == p_in) | 1254 && CSELIB_VAL_PTR (p->loc)->locs == p_in) |
1112 continue; | 1255 continue; |
1113 else if (!REG_P (p->loc)) | 1256 else if (!REG_P (p->loc)) |
1114 { | 1257 { |
1115 rtx result, note; | 1258 rtx result, note; |
1116 if (dump_file && (dump_flags & TDF_DETAILS)) | 1259 if (dump_file && (dump_flags & TDF_CSELIB)) |
1117 { | 1260 { |
1118 print_inline_rtx (dump_file, p->loc, 0); | 1261 print_inline_rtx (dump_file, p->loc, 0); |
1119 fprintf (dump_file, "\n"); | 1262 fprintf (dump_file, "\n"); |
1120 } | 1263 } |
1121 if (GET_CODE (p->loc) == LO_SUM | 1264 if (GET_CODE (p->loc) == LO_SUM |
1132 } | 1275 } |
1133 | 1276 |
1134 if (regno != UINT_MAX) | 1277 if (regno != UINT_MAX) |
1135 { | 1278 { |
1136 rtx result; | 1279 rtx result; |
1137 if (dump_file && (dump_flags & TDF_DETAILS)) | 1280 if (dump_file && (dump_flags & TDF_CSELIB)) |
1138 fprintf (dump_file, "r%d\n", regno); | 1281 fprintf (dump_file, "r%d\n", regno); |
1139 | 1282 |
1140 result = cselib_expand_value_rtx_1 (reg_result, evd, max_depth - 1); | 1283 result = cselib_expand_value_rtx_1 (reg_result, evd, max_depth - 1); |
1141 if (result) | 1284 if (result) |
1142 return result; | 1285 return result; |
1143 } | 1286 } |
1144 | 1287 |
1145 if (dump_file && (dump_flags & TDF_DETAILS)) | 1288 if (dump_file && (dump_flags & TDF_CSELIB)) |
1146 { | 1289 { |
1147 if (reg_result) | 1290 if (reg_result) |
1148 { | 1291 { |
1149 print_inline_rtx (dump_file, reg_result, 0); | 1292 print_inline_rtx (dump_file, reg_result, 0); |
1150 fprintf (dump_file, "\n"); | 1293 fprintf (dump_file, "\n"); |
1281 || regno == HARD_FRAME_POINTER_REGNUM) | 1424 || regno == HARD_FRAME_POINTER_REGNUM) |
1282 return orig; | 1425 return orig; |
1283 | 1426 |
1284 bitmap_set_bit (evd->regs_active, regno); | 1427 bitmap_set_bit (evd->regs_active, regno); |
1285 | 1428 |
1286 if (dump_file && (dump_flags & TDF_DETAILS)) | 1429 if (dump_file && (dump_flags & TDF_CSELIB)) |
1287 fprintf (dump_file, "expanding: r%d into: ", regno); | 1430 fprintf (dump_file, "expanding: r%d into: ", regno); |
1288 | 1431 |
1289 result = expand_loc (l->elt->locs, evd, max_depth); | 1432 result = expand_loc (l->elt->locs, evd, max_depth); |
1290 bitmap_clear_bit (evd->regs_active, regno); | 1433 bitmap_clear_bit (evd->regs_active, regno); |
1291 | 1434 |
1346 | 1489 |
1347 case VALUE: | 1490 case VALUE: |
1348 { | 1491 { |
1349 rtx result; | 1492 rtx result; |
1350 | 1493 |
1351 if (dump_file && (dump_flags & TDF_DETAILS)) | 1494 if (dump_file && (dump_flags & TDF_CSELIB)) |
1352 { | 1495 { |
1353 fputs ("\nexpanding ", dump_file); | 1496 fputs ("\nexpanding ", dump_file); |
1354 print_rtl_single (dump_file, orig); | 1497 print_rtl_single (dump_file, orig); |
1355 fputs (" into...", dump_file); | 1498 fputs (" into...", dump_file); |
1356 } | 1499 } |
1505 | 1648 |
1506 /* Walk rtx X and replace all occurrences of REG and MEM subexpressions | 1649 /* Walk rtx X and replace all occurrences of REG and MEM subexpressions |
1507 with VALUE expressions. This way, it becomes independent of changes | 1650 with VALUE expressions. This way, it becomes independent of changes |
1508 to registers and memory. | 1651 to registers and memory. |
1509 X isn't actually modified; if modifications are needed, new rtl is | 1652 X isn't actually modified; if modifications are needed, new rtl is |
1510 allocated. However, the return value can share rtl with X. */ | 1653 allocated. However, the return value can share rtl with X. |
1654 If X is within a MEM, MEMMODE must be the mode of the MEM. */ | |
1511 | 1655 |
1512 rtx | 1656 rtx |
1513 cselib_subst_to_values (rtx x) | 1657 cselib_subst_to_values (rtx x, enum machine_mode memmode) |
1514 { | 1658 { |
1515 enum rtx_code code = GET_CODE (x); | 1659 enum rtx_code code = GET_CODE (x); |
1516 const char *fmt = GET_RTX_FORMAT (code); | 1660 const char *fmt = GET_RTX_FORMAT (code); |
1517 cselib_val *e; | 1661 cselib_val *e; |
1518 struct elt_list *l; | 1662 struct elt_list *l; |
1531 | 1675 |
1532 gcc_unreachable (); | 1676 gcc_unreachable (); |
1533 | 1677 |
1534 case MEM: | 1678 case MEM: |
1535 e = cselib_lookup_mem (x, 0); | 1679 e = cselib_lookup_mem (x, 0); |
1680 /* This used to happen for autoincrements, but we deal with them | |
1681 properly now. Remove the if stmt for the next release. */ | |
1536 if (! e) | 1682 if (! e) |
1537 { | 1683 { |
1538 /* This happens for autoincrements. Assign a value that doesn't | 1684 /* Assign a value that doesn't match any other. */ |
1539 match any other. */ | |
1540 e = new_cselib_val (next_uid, GET_MODE (x), x); | 1685 e = new_cselib_val (next_uid, GET_MODE (x), x); |
1541 } | 1686 } |
1542 return e->val_rtx; | 1687 return e->val_rtx; |
1543 | 1688 |
1544 case CONST_DOUBLE: | 1689 case CONST_DOUBLE: |
1545 case CONST_VECTOR: | 1690 case CONST_VECTOR: |
1546 case CONST_INT: | 1691 case CONST_INT: |
1547 case CONST_FIXED: | 1692 case CONST_FIXED: |
1548 return x; | 1693 return x; |
1549 | 1694 |
1695 case PRE_DEC: | |
1696 case PRE_INC: | |
1697 gcc_assert (memmode != VOIDmode); | |
1698 i = GET_MODE_SIZE (memmode); | |
1699 if (code == PRE_DEC) | |
1700 i = -i; | |
1701 return cselib_subst_to_values (plus_constant (XEXP (x, 0), i), | |
1702 memmode); | |
1703 | |
1704 case PRE_MODIFY: | |
1705 gcc_assert (memmode != VOIDmode); | |
1706 return cselib_subst_to_values (XEXP (x, 1), memmode); | |
1707 | |
1708 case POST_DEC: | |
1550 case POST_INC: | 1709 case POST_INC: |
1551 case PRE_INC: | |
1552 case POST_DEC: | |
1553 case PRE_DEC: | |
1554 case POST_MODIFY: | 1710 case POST_MODIFY: |
1555 case PRE_MODIFY: | 1711 gcc_assert (memmode != VOIDmode); |
1556 e = new_cselib_val (next_uid, GET_MODE (x), x); | 1712 return cselib_subst_to_values (XEXP (x, 0), memmode); |
1557 return e->val_rtx; | |
1558 | 1713 |
1559 default: | 1714 default: |
1560 break; | 1715 break; |
1561 } | 1716 } |
1562 | 1717 |
1563 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | 1718 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) |
1564 { | 1719 { |
1565 if (fmt[i] == 'e') | 1720 if (fmt[i] == 'e') |
1566 { | 1721 { |
1567 rtx t = cselib_subst_to_values (XEXP (x, i)); | 1722 rtx t = cselib_subst_to_values (XEXP (x, i), memmode); |
1568 | 1723 |
1569 if (t != XEXP (x, i)) | 1724 if (t != XEXP (x, i)) |
1570 { | 1725 { |
1571 if (x == copy) | 1726 if (x == copy) |
1572 copy = shallow_copy_rtx (x); | 1727 copy = shallow_copy_rtx (x); |
1577 { | 1732 { |
1578 int j; | 1733 int j; |
1579 | 1734 |
1580 for (j = 0; j < XVECLEN (x, i); j++) | 1735 for (j = 0; j < XVECLEN (x, i); j++) |
1581 { | 1736 { |
1582 rtx t = cselib_subst_to_values (XVECEXP (x, i, j)); | 1737 rtx t = cselib_subst_to_values (XVECEXP (x, i, j), memmode); |
1583 | 1738 |
1584 if (t != XVECEXP (x, i, j)) | 1739 if (t != XVECEXP (x, i, j)) |
1585 { | 1740 { |
1586 if (XVEC (x, i) == XVEC (copy, i)) | 1741 if (XVEC (x, i) == XVEC (copy, i)) |
1587 { | 1742 { |
1596 } | 1751 } |
1597 | 1752 |
1598 return copy; | 1753 return copy; |
1599 } | 1754 } |
1600 | 1755 |
1601 /* Look up the rtl expression X in our tables and return the value it has. | 1756 /* Look up the rtl expression X in our tables and return the value it |
1602 If CREATE is zero, we return NULL if we don't know the value. Otherwise, | 1757 has. If CREATE is zero, we return NULL if we don't know the value. |
1603 we create a new one if possible, using mode MODE if X doesn't have a mode | 1758 Otherwise, we create a new one if possible, using mode MODE if X |
1604 (i.e. because it's a constant). */ | 1759 doesn't have a mode (i.e. because it's a constant). When X is part |
1760 of an address, MEMMODE should be the mode of the enclosing MEM if | |
1761 we're tracking autoinc expressions. */ | |
1605 | 1762 |
1606 static cselib_val * | 1763 static cselib_val * |
1607 cselib_lookup_1 (rtx x, enum machine_mode mode, int create) | 1764 cselib_lookup_1 (rtx x, enum machine_mode mode, |
1765 int create, enum machine_mode memmode) | |
1608 { | 1766 { |
1609 void **slot; | 1767 void **slot; |
1610 cselib_val *e; | 1768 cselib_val *e; |
1611 unsigned int hashval; | 1769 unsigned int hashval; |
1612 | 1770 |
1651 register, or NULL. */ | 1809 register, or NULL. */ |
1652 used_regs[n_used_regs++] = i; | 1810 used_regs[n_used_regs++] = i; |
1653 REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL); | 1811 REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL); |
1654 } | 1812 } |
1655 REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e); | 1813 REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e); |
1656 slot = htab_find_slot_with_hash (cselib_hash_table, x, e->hash, INSERT); | 1814 slot = cselib_find_slot (x, e->hash, INSERT, memmode); |
1657 *slot = e; | 1815 *slot = e; |
1658 return e; | 1816 return e; |
1659 } | 1817 } |
1660 | 1818 |
1661 if (MEM_P (x)) | 1819 if (MEM_P (x)) |
1662 return cselib_lookup_mem (x, create); | 1820 return cselib_lookup_mem (x, create); |
1663 | 1821 |
1664 hashval = cselib_hash_rtx (x, create); | 1822 hashval = cselib_hash_rtx (x, create, memmode); |
1665 /* Can't even create if hashing is not possible. */ | 1823 /* Can't even create if hashing is not possible. */ |
1666 if (! hashval) | 1824 if (! hashval) |
1667 return 0; | 1825 return 0; |
1668 | 1826 |
1669 slot = htab_find_slot_with_hash (cselib_hash_table, wrap_constant (mode, x), | 1827 slot = cselib_find_slot (wrap_constant (mode, x), hashval, |
1670 hashval, create ? INSERT : NO_INSERT); | 1828 create ? INSERT : NO_INSERT, memmode); |
1671 if (slot == 0) | 1829 if (slot == 0) |
1672 return 0; | 1830 return 0; |
1673 | 1831 |
1674 e = (cselib_val *) *slot; | 1832 e = (cselib_val *) *slot; |
1675 if (e) | 1833 if (e) |
1679 | 1837 |
1680 /* We have to fill the slot before calling cselib_subst_to_values: | 1838 /* We have to fill the slot before calling cselib_subst_to_values: |
1681 the hash table is inconsistent until we do so, and | 1839 the hash table is inconsistent until we do so, and |
1682 cselib_subst_to_values will need to do lookups. */ | 1840 cselib_subst_to_values will need to do lookups. */ |
1683 *slot = (void *) e; | 1841 *slot = (void *) e; |
1684 e->locs = new_elt_loc_list (e->locs, cselib_subst_to_values (x)); | 1842 e->locs = new_elt_loc_list (e->locs, |
1843 cselib_subst_to_values (x, memmode)); | |
1685 return e; | 1844 return e; |
1686 } | 1845 } |
1687 | 1846 |
1688 /* Wrapper for cselib_lookup, that indicates X is in INSN. */ | 1847 /* Wrapper for cselib_lookup, that indicates X is in INSN. */ |
1689 | 1848 |
1690 cselib_val * | 1849 cselib_val * |
1691 cselib_lookup_from_insn (rtx x, enum machine_mode mode, | 1850 cselib_lookup_from_insn (rtx x, enum machine_mode mode, |
1692 int create, rtx insn) | 1851 int create, enum machine_mode memmode, rtx insn) |
1693 { | 1852 { |
1694 cselib_val *ret; | 1853 cselib_val *ret; |
1695 | 1854 |
1696 gcc_assert (!cselib_current_insn); | 1855 gcc_assert (!cselib_current_insn); |
1697 cselib_current_insn = insn; | 1856 cselib_current_insn = insn; |
1698 | 1857 |
1699 ret = cselib_lookup (x, mode, create); | 1858 ret = cselib_lookup (x, mode, create, memmode); |
1700 | 1859 |
1701 cselib_current_insn = NULL; | 1860 cselib_current_insn = NULL; |
1702 | 1861 |
1703 return ret; | 1862 return ret; |
1704 } | 1863 } |
1705 | 1864 |
1706 /* Wrapper for cselib_lookup_1, that logs the lookup result and | 1865 /* Wrapper for cselib_lookup_1, that logs the lookup result and |
1707 maintains invariants related with debug insns. */ | 1866 maintains invariants related with debug insns. */ |
1708 | 1867 |
1709 cselib_val * | 1868 cselib_val * |
1710 cselib_lookup (rtx x, enum machine_mode mode, int create) | 1869 cselib_lookup (rtx x, enum machine_mode mode, |
1711 { | 1870 int create, enum machine_mode memmode) |
1712 cselib_val *ret = cselib_lookup_1 (x, mode, create); | 1871 { |
1872 cselib_val *ret = cselib_lookup_1 (x, mode, create, memmode); | |
1713 | 1873 |
1714 /* ??? Should we return NULL if we're not to create an entry, the | 1874 /* ??? Should we return NULL if we're not to create an entry, the |
1715 found loc is a debug loc and cselib_current_insn is not DEBUG? | 1875 found loc is a debug loc and cselib_current_insn is not DEBUG? |
1716 If so, we should also avoid converting val to non-DEBUG; probably | 1876 If so, we should also avoid converting val to non-DEBUG; probably |
1717 easiest setting cselib_current_insn to NULL before the call | 1877 easiest setting cselib_current_insn to NULL before the call |
1718 above. */ | 1878 above. */ |
1719 | 1879 |
1720 if (dump_file && (dump_flags & TDF_DETAILS)) | 1880 if (dump_file && (dump_flags & TDF_CSELIB)) |
1721 { | 1881 { |
1722 fputs ("cselib lookup ", dump_file); | 1882 fputs ("cselib lookup ", dump_file); |
1723 print_inline_rtx (dump_file, x, 2); | 1883 print_inline_rtx (dump_file, x, 2); |
1724 fprintf (dump_file, " => %u:%u\n", | 1884 fprintf (dump_file, " => %u:%u\n", |
1725 ret ? ret->uid : 0, | 1885 ret ? ret->uid : 0, |
1781 unsigned int this_last = i; | 1941 unsigned int this_last = i; |
1782 | 1942 |
1783 if (i < FIRST_PSEUDO_REGISTER && v != NULL) | 1943 if (i < FIRST_PSEUDO_REGISTER && v != NULL) |
1784 this_last = end_hard_regno (GET_MODE (v->val_rtx), i) - 1; | 1944 this_last = end_hard_regno (GET_MODE (v->val_rtx), i) - 1; |
1785 | 1945 |
1786 if (this_last < regno || v == NULL || v == cfa_base_preserved_val) | 1946 if (this_last < regno || v == NULL |
1947 || (v == cfa_base_preserved_val | |
1948 && i == cfa_base_preserved_regno)) | |
1787 { | 1949 { |
1788 l = &(*l)->next; | 1950 l = &(*l)->next; |
1789 continue; | 1951 continue; |
1790 } | 1952 } |
1791 | 1953 |
1890 } | 2052 } |
1891 | 2053 |
1892 /* This one overlaps. */ | 2054 /* This one overlaps. */ |
1893 /* We must have a mapping from this MEM's address to the | 2055 /* We must have a mapping from this MEM's address to the |
1894 value (E). Remove that, too. */ | 2056 value (E). Remove that, too. */ |
1895 addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0); | 2057 addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0, GET_MODE (x)); |
1896 mem_chain = &addr->addr_list; | 2058 mem_chain = &addr->addr_list; |
1897 for (;;) | 2059 for (;;) |
1898 { | 2060 { |
1899 if ((*mem_chain)->elt == v) | 2061 if ((*mem_chain)->elt == v) |
1900 { | 2062 { |
1940 | 2102 |
1941 if (REG_P (dest)) | 2103 if (REG_P (dest)) |
1942 cselib_invalidate_regno (REGNO (dest), GET_MODE (dest)); | 2104 cselib_invalidate_regno (REGNO (dest), GET_MODE (dest)); |
1943 else if (MEM_P (dest)) | 2105 else if (MEM_P (dest)) |
1944 cselib_invalidate_mem (dest); | 2106 cselib_invalidate_mem (dest); |
1945 | |
1946 /* Some machines don't define AUTO_INC_DEC, but they still use push | |
1947 instructions. We need to catch that case here in order to | |
1948 invalidate the stack pointer correctly. Note that invalidating | |
1949 the stack pointer is different from invalidating DEST. */ | |
1950 if (push_operand (dest, GET_MODE (dest))) | |
1951 cselib_invalidate_rtx (stack_pointer_rtx); | |
1952 } | 2107 } |
1953 | 2108 |
1954 /* A wrapper for cselib_invalidate_rtx to be called via note_stores. */ | 2109 /* A wrapper for cselib_invalidate_rtx to be called via note_stores. */ |
1955 | 2110 |
1956 static void | 2111 static void |
2009 | 2164 |
2010 /* There is no good way to determine how many elements there can be | 2165 /* There is no good way to determine how many elements there can be |
2011 in a PARALLEL. Since it's fairly cheap, use a really large number. */ | 2166 in a PARALLEL. Since it's fairly cheap, use a really large number. */ |
2012 #define MAX_SETS (FIRST_PSEUDO_REGISTER * 2) | 2167 #define MAX_SETS (FIRST_PSEUDO_REGISTER * 2) |
2013 | 2168 |
2014 /* Record the effects of any sets in INSN. */ | 2169 struct cselib_record_autoinc_data |
2170 { | |
2171 struct cselib_set *sets; | |
2172 int n_sets; | |
2173 }; | |
2174 | |
2175 /* Callback for for_each_inc_dec. Records in ARG the SETs implied by | |
2176 autoinc RTXs: SRC plus SRCOFF if non-NULL is stored in DEST. */ | |
2177 | |
2178 static int | |
2179 cselib_record_autoinc_cb (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED, | |
2180 rtx dest, rtx src, rtx srcoff, void *arg) | |
2181 { | |
2182 struct cselib_record_autoinc_data *data; | |
2183 data = (struct cselib_record_autoinc_data *)arg; | |
2184 | |
2185 data->sets[data->n_sets].dest = dest; | |
2186 | |
2187 if (srcoff) | |
2188 data->sets[data->n_sets].src = gen_rtx_PLUS (GET_MODE (src), src, srcoff); | |
2189 else | |
2190 data->sets[data->n_sets].src = src; | |
2191 | |
2192 data->n_sets++; | |
2193 | |
2194 return -1; | |
2195 } | |
2196 | |
2197 /* Record the effects of any sets and autoincs in INSN. */ | |
2015 static void | 2198 static void |
2016 cselib_record_sets (rtx insn) | 2199 cselib_record_sets (rtx insn) |
2017 { | 2200 { |
2018 int n_sets = 0; | 2201 int n_sets = 0; |
2019 int i; | 2202 int i; |
2020 struct cselib_set sets[MAX_SETS]; | 2203 struct cselib_set sets[MAX_SETS]; |
2021 rtx body = PATTERN (insn); | 2204 rtx body = PATTERN (insn); |
2022 rtx cond = 0; | 2205 rtx cond = 0; |
2206 int n_sets_before_autoinc; | |
2207 struct cselib_record_autoinc_data data; | |
2023 | 2208 |
2024 body = PATTERN (insn); | 2209 body = PATTERN (insn); |
2025 if (GET_CODE (body) == COND_EXEC) | 2210 if (GET_CODE (body) == COND_EXEC) |
2026 { | 2211 { |
2027 cond = COND_EXEC_TEST (body); | 2212 cond = COND_EXEC_TEST (body); |
2060 rtx note = find_reg_equal_equiv_note (insn); | 2245 rtx note = find_reg_equal_equiv_note (insn); |
2061 | 2246 |
2062 if (note && CONSTANT_P (XEXP (note, 0))) | 2247 if (note && CONSTANT_P (XEXP (note, 0))) |
2063 sets[0].src = XEXP (note, 0); | 2248 sets[0].src = XEXP (note, 0); |
2064 } | 2249 } |
2250 | |
2251 data.sets = sets; | |
2252 data.n_sets = n_sets_before_autoinc = n_sets; | |
2253 for_each_inc_dec (&insn, cselib_record_autoinc_cb, &data); | |
2254 n_sets = data.n_sets; | |
2065 | 2255 |
2066 /* Look up the values that are read. Do this before invalidating the | 2256 /* Look up the values that are read. Do this before invalidating the |
2067 locations that are written. */ | 2257 locations that are written. */ |
2068 for (i = 0; i < n_sets; i++) | 2258 for (i = 0; i < n_sets; i++) |
2069 { | 2259 { |
2079 || (MEM_P (dest) && cselib_record_memory)) | 2269 || (MEM_P (dest) && cselib_record_memory)) |
2080 { | 2270 { |
2081 rtx src = sets[i].src; | 2271 rtx src = sets[i].src; |
2082 if (cond) | 2272 if (cond) |
2083 src = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, src, dest); | 2273 src = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, src, dest); |
2084 sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1); | 2274 sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1, VOIDmode); |
2085 if (MEM_P (dest)) | 2275 if (MEM_P (dest)) |
2086 { | 2276 { |
2087 enum machine_mode address_mode | 2277 enum machine_mode address_mode |
2088 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest)); | 2278 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest)); |
2089 | 2279 |
2090 sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), | 2280 sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), |
2091 address_mode, 1); | 2281 address_mode, 1, |
2282 GET_MODE (dest)); | |
2092 } | 2283 } |
2093 else | 2284 else |
2094 sets[i].dest_addr_elt = 0; | 2285 sets[i].dest_addr_elt = 0; |
2095 } | 2286 } |
2096 } | 2287 } |
2100 | 2291 |
2101 /* Invalidate all locations written by this insn. Note that the elts we | 2292 /* Invalidate all locations written by this insn. Note that the elts we |
2102 looked up in the previous loop aren't affected, just some of their | 2293 looked up in the previous loop aren't affected, just some of their |
2103 locations may go away. */ | 2294 locations may go away. */ |
2104 note_stores (body, cselib_invalidate_rtx_note_stores, NULL); | 2295 note_stores (body, cselib_invalidate_rtx_note_stores, NULL); |
2296 | |
2297 for (i = n_sets_before_autoinc; i < n_sets; i++) | |
2298 cselib_invalidate_rtx (sets[i].dest); | |
2105 | 2299 |
2106 /* If this is an asm, look for duplicate sets. This can happen when the | 2300 /* If this is an asm, look for duplicate sets. This can happen when the |
2107 user uses the same value as an output multiple times. This is valid | 2301 user uses the same value as an output multiple times. This is valid |
2108 if the outputs are not actually used thereafter. Treat this case as | 2302 if the outputs are not actually used thereafter. Treat this case as |
2109 if the value isn't actually set. We do this by smashing the destination | 2303 if the value isn't actually set. We do this by smashing the destination |
2185 cselib_invalidate_mem (callmem); | 2379 cselib_invalidate_mem (callmem); |
2186 } | 2380 } |
2187 | 2381 |
2188 cselib_record_sets (insn); | 2382 cselib_record_sets (insn); |
2189 | 2383 |
2190 #ifdef AUTO_INC_DEC | |
2191 /* Clobber any registers which appear in REG_INC notes. We | |
2192 could keep track of the changes to their values, but it is | |
2193 unlikely to help. */ | |
2194 for (x = REG_NOTES (insn); x; x = XEXP (x, 1)) | |
2195 if (REG_NOTE_KIND (x) == REG_INC) | |
2196 cselib_invalidate_rtx (XEXP (x, 0)); | |
2197 #endif | |
2198 | |
2199 /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only | 2384 /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only |
2200 after we have processed the insn. */ | 2385 after we have processed the insn. */ |
2201 if (CALL_P (insn)) | 2386 if (CALL_P (insn)) |
2202 for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) | 2387 for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) |
2203 if (GET_CODE (XEXP (x, 0)) == CLOBBER) | 2388 if (GET_CODE (XEXP (x, 0)) == CLOBBER) |
2264 cselib_finish (void) | 2449 cselib_finish (void) |
2265 { | 2450 { |
2266 cselib_discard_hook = NULL; | 2451 cselib_discard_hook = NULL; |
2267 cselib_preserve_constants = false; | 2452 cselib_preserve_constants = false; |
2268 cfa_base_preserved_val = NULL; | 2453 cfa_base_preserved_val = NULL; |
2454 cfa_base_preserved_regno = INVALID_REGNUM; | |
2269 free_alloc_pool (elt_list_pool); | 2455 free_alloc_pool (elt_list_pool); |
2270 free_alloc_pool (elt_loc_list_pool); | 2456 free_alloc_pool (elt_loc_list_pool); |
2271 free_alloc_pool (cselib_val_pool); | 2457 free_alloc_pool (cselib_val_pool); |
2272 free_alloc_pool (value_pool); | 2458 free_alloc_pool (value_pool); |
2273 cselib_clear_table (); | 2459 cselib_clear_table (); |