comparison gcc/lra-eliminations.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Code for RTL register eliminations. 1 /* Code for RTL register eliminations.
2 Copyright (C) 2010-2018 Free Software Foundation, Inc. 2 Copyright (C) 2010-2020 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>. 3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
69 #include "rtl-error.h" 69 #include "rtl-error.h"
70 #include "lra-int.h" 70 #include "lra-int.h"
71 71
72 /* This structure is used to record information about hard register 72 /* This structure is used to record information about hard register
73 eliminations. */ 73 eliminations. */
74 struct lra_elim_table 74 class lra_elim_table
75 { 75 {
76 public:
76 /* Hard register number to be eliminated. */ 77 /* Hard register number to be eliminated. */
77 int from; 78 int from;
78 /* Hard register number used as replacement. */ 79 /* Hard register number used as replacement. */
79 int to; 80 int to;
80 /* Difference between values of the two hard registers above on 81 /* Difference between values of the two hard registers above on
97 98
98 /* The elimination table. Each array entry describes one possible way 99 /* The elimination table. Each array entry describes one possible way
99 of eliminating a register in favor of another. If there is more 100 of eliminating a register in favor of another. If there is more
100 than one way of eliminating a particular register, the most 101 than one way of eliminating a particular register, the most
101 preferred should be specified first. */ 102 preferred should be specified first. */
102 static struct lra_elim_table *reg_eliminate = 0; 103 static class lra_elim_table *reg_eliminate = 0;
103 104
104 /* This is an intermediate structure to initialize the table. It has 105 /* This is an intermediate structure to initialize the table. It has
105 exactly the members provided by ELIMINABLE_REGS. */ 106 exactly the members provided by ELIMINABLE_REGS. */
106 static const struct elim_table_1 107 static const struct elim_table_1
107 { 108 {
115 116
116 /* Print info about elimination table to file F. */ 117 /* Print info about elimination table to file F. */
117 static void 118 static void
118 print_elim_table (FILE *f) 119 print_elim_table (FILE *f)
119 { 120 {
120 struct lra_elim_table *ep; 121 class lra_elim_table *ep;
121 122
122 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++) 123 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
123 { 124 {
124 fprintf (f, "%s eliminate %d to %d (offset=", 125 fprintf (f, "%s eliminate %d to %d (offset=",
125 ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to); 126 ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to);
139 140
140 /* Setup possibility of elimination in elimination table element EP to 141 /* Setup possibility of elimination in elimination table element EP to
141 VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame 142 VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame
142 pointer to stack pointer is not possible anymore. */ 143 pointer to stack pointer is not possible anymore. */
143 static void 144 static void
144 setup_can_eliminate (struct lra_elim_table *ep, bool value) 145 setup_can_eliminate (class lra_elim_table *ep, bool value)
145 { 146 {
146 ep->can_eliminate = ep->prev_can_eliminate = value; 147 ep->can_eliminate = ep->prev_can_eliminate = value;
147 if (! value 148 if (! value
148 && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) 149 && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
149 frame_pointer_needed = 1; 150 frame_pointer_needed = 1;
153 154
154 /* Map: eliminable "from" register -> its current elimination, 155 /* Map: eliminable "from" register -> its current elimination,
155 or NULL if none. The elimination table may contain more than 156 or NULL if none. The elimination table may contain more than
156 one elimination for the same hard register, but this map specifies 157 one elimination for the same hard register, but this map specifies
157 the one that we are currently using. */ 158 the one that we are currently using. */
158 static struct lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER]; 159 static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
159 160
160 /* When an eliminable hard register becomes not eliminable, we use the 161 /* When an eliminable hard register becomes not eliminable, we use the
161 following special structure to restore original offsets for the 162 following special structure to restore original offsets for the
162 register. */ 163 register. */
163 static struct lra_elim_table self_elim_table; 164 static class lra_elim_table self_elim_table;
164 165
165 /* Offsets should be used to restore original offsets for eliminable 166 /* Offsets should be used to restore original offsets for eliminable
166 hard register which just became not eliminable. Zero, 167 hard register which just became not eliminable. Zero,
167 otherwise. */ 168 otherwise. */
168 static poly_int64_pod self_elim_offsets[FIRST_PSEUDO_REGISTER]; 169 static poly_int64_pod self_elim_offsets[FIRST_PSEUDO_REGISTER];
174 /* Set up ELIMINATION_MAP of the currently used eliminations. */ 175 /* Set up ELIMINATION_MAP of the currently used eliminations. */
175 static void 176 static void
176 setup_elimination_map (void) 177 setup_elimination_map (void)
177 { 178 {
178 int i; 179 int i;
179 struct lra_elim_table *ep; 180 class lra_elim_table *ep;
180 181
181 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 182 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
182 elimination_map[i] = NULL; 183 elimination_map[i] = NULL;
183 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++) 184 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
184 if (ep->can_eliminate && elimination_map[ep->from] == NULL) 185 if (ep->can_eliminate && elimination_map[ep->from] == NULL)
239 /* Return the current substitution hard register of the elimination of 240 /* Return the current substitution hard register of the elimination of
240 HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */ 241 HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */
241 int 242 int
242 lra_get_elimination_hard_regno (int hard_regno) 243 lra_get_elimination_hard_regno (int hard_regno)
243 { 244 {
244 struct lra_elim_table *ep; 245 class lra_elim_table *ep;
245 246
246 if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) 247 if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
247 return hard_regno; 248 return hard_regno;
248 if ((ep = elimination_map[hard_regno]) == NULL) 249 if ((ep = elimination_map[hard_regno]) == NULL)
249 return hard_regno; 250 return hard_regno;
250 return ep->to; 251 return ep->to;
251 } 252 }
252 253
253 /* Return elimination which will be used for hard reg REG, NULL 254 /* Return elimination which will be used for hard reg REG, NULL
254 otherwise. */ 255 otherwise. */
255 static struct lra_elim_table * 256 static class lra_elim_table *
256 get_elimination (rtx reg) 257 get_elimination (rtx reg)
257 { 258 {
258 int hard_regno; 259 int hard_regno;
259 struct lra_elim_table *ep; 260 class lra_elim_table *ep;
260 261
261 lra_assert (REG_P (reg)); 262 lra_assert (REG_P (reg));
262 if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) 263 if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
263 return NULL; 264 return NULL;
264 if ((ep = elimination_map[hard_regno]) != NULL) 265 if ((ep = elimination_map[hard_regno]) != NULL)
331 lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, 332 lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
332 bool subst_p, bool update_p, 333 bool subst_p, bool update_p,
333 poly_int64 update_sp_offset, bool full_p) 334 poly_int64 update_sp_offset, bool full_p)
334 { 335 {
335 enum rtx_code code = GET_CODE (x); 336 enum rtx_code code = GET_CODE (x);
336 struct lra_elim_table *ep; 337 class lra_elim_table *ep;
337 rtx new_rtx; 338 rtx new_rtx;
338 int i, j; 339 int i, j;
339 const char *fmt; 340 const char *fmt;
340 int copied = 0; 341 int copied = 0;
341 342
652 if (new_rtx != XEXP (x, 0)) 653 if (new_rtx != XEXP (x, 0))
653 return gen_rtx_USE (GET_MODE (x), new_rtx); 654 return gen_rtx_USE (GET_MODE (x), new_rtx);
654 return x; 655 return x;
655 656
656 case CLOBBER: 657 case CLOBBER:
657 case CLOBBER_HIGH:
658 case SET: 658 case SET:
659 gcc_unreachable (); 659 gcc_unreachable ();
660 660
661 default: 661 default:
662 break; 662 break;
728 within a MEM. */ 728 within a MEM. */
729 static void 729 static void
730 mark_not_eliminable (rtx x, machine_mode mem_mode) 730 mark_not_eliminable (rtx x, machine_mode mem_mode)
731 { 731 {
732 enum rtx_code code = GET_CODE (x); 732 enum rtx_code code = GET_CODE (x);
733 struct lra_elim_table *ep; 733 class lra_elim_table *ep;
734 int i, j; 734 int i, j;
735 const char *fmt; 735 const char *fmt;
736 poly_int64 offset = 0; 736 poly_int64 offset = 0;
737 737
738 switch (code) 738 switch (code)
803 ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; 803 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
804 ep++) 804 ep++)
805 if (ep->to_rtx == XEXP (x, 0) 805 if (ep->to_rtx == XEXP (x, 0)
806 && ep->to_rtx != hard_frame_pointer_rtx) 806 && ep->to_rtx != hard_frame_pointer_rtx)
807 setup_can_eliminate (ep, false); 807 setup_can_eliminate (ep, false);
808 return;
809
810 case CLOBBER_HIGH:
811 gcc_assert (REG_P (XEXP (x, 0)));
812 gcc_assert (REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER);
813 for (ep = reg_eliminate;
814 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
815 ep++)
816 if (reg_is_clobbered_by_clobber_high (ep->to_rtx, XEXP (x, 0)))
817 setup_can_eliminate (ep, false);
818 return; 808 return;
819 809
820 case SET: 810 case SET:
821 if (SET_DEST (x) == stack_pointer_rtx 811 if (SET_DEST (x) == stack_pointer_rtx
822 && GET_CODE (SET_SRC (x)) == PLUS 812 && GET_CODE (SET_SRC (x)) == PLUS
874 } 864 }
875 } 865 }
876 866
877 867
878 868
879 #ifdef HARD_FRAME_POINTER_REGNUM
880
881 /* Search INSN's reg notes to see whether the destination is equal to
882 WHAT + C for some constant C. Return true if so, storing C in
883 *OFFSET_OUT and removing the reg note. */
884 static bool
885 remove_reg_equal_offset_note (rtx_insn *insn, rtx what, poly_int64 *offset_out)
886 {
887 rtx link, *link_loc;
888
889 for (link_loc = &REG_NOTES (insn);
890 (link = *link_loc) != NULL_RTX;
891 link_loc = &XEXP (link, 1))
892 if (REG_NOTE_KIND (link) == REG_EQUAL
893 && GET_CODE (XEXP (link, 0)) == PLUS
894 && XEXP (XEXP (link, 0), 0) == what
895 && poly_int_rtx_p (XEXP (XEXP (link, 0), 1), offset_out))
896 {
897 *link_loc = XEXP (link, 1);
898 return true;
899 }
900 return false;
901 }
902
903 #endif
904
905 /* Scan INSN and eliminate all eliminable hard registers in it. 869 /* Scan INSN and eliminate all eliminable hard registers in it.
906 870
907 If REPLACE_P is true, do the replacement destructively. Also 871 If REPLACE_P is true, do the replacement destructively. Also
908 delete the insn as dead it if it is setting an eliminable register. 872 delete the insn as dead it if it is setting an eliminable register.
909 873
924 rtx old_set = single_set (insn); 888 rtx old_set = single_set (insn);
925 bool validate_p; 889 bool validate_p;
926 int i; 890 int i;
927 rtx substed_operand[MAX_RECOG_OPERANDS]; 891 rtx substed_operand[MAX_RECOG_OPERANDS];
928 rtx orig_operand[MAX_RECOG_OPERANDS]; 892 rtx orig_operand[MAX_RECOG_OPERANDS];
929 struct lra_elim_table *ep; 893 class lra_elim_table *ep;
930 rtx plus_src, plus_cst_src; 894 rtx plus_src, plus_cst_src;
931 lra_insn_recog_data_t id; 895 lra_insn_recog_data_t id;
932 struct lra_static_insn_data *static_id; 896 struct lra_static_insn_data *static_id;
933 897
934 if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn)) 898 if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn))
935 { 899 {
936 lra_assert (GET_CODE (PATTERN (insn)) == USE 900 lra_assert (GET_CODE (PATTERN (insn)) == USE
937 || GET_CODE (PATTERN (insn)) == CLOBBER 901 || GET_CODE (PATTERN (insn)) == CLOBBER
938 || GET_CODE (PATTERN (insn)) == ASM_INPUT); 902 || GET_CODE (PATTERN (insn)) == ASM_INPUT);
939 return; 903 return;
940 }
941
942 /* Check for setting an eliminable register. */
943 if (old_set != 0 && REG_P (SET_DEST (old_set))
944 && (ep = get_elimination (SET_DEST (old_set))) != NULL)
945 {
946 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
947 if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate)
948 {
949 bool delete_p = replace_p;
950
951 #ifdef HARD_FRAME_POINTER_REGNUM
952 if (ep->from == FRAME_POINTER_REGNUM
953 && ep->to == HARD_FRAME_POINTER_REGNUM)
954 /* If this is setting the frame pointer register to the
955 hardware frame pointer register and this is an
956 elimination that will be done (tested above), this
957 insn is really adjusting the frame pointer downward
958 to compensate for the adjustment done before a
959 nonlocal goto. */
960 {
961 rtx src = SET_SRC (old_set);
962 poly_int64 offset = 0;
963
964 /* We should never process such insn with non-zero
965 UPDATE_SP_OFFSET. */
966 lra_assert (known_eq (update_sp_offset, 0));
967
968 if (remove_reg_equal_offset_note (insn, ep->to_rtx, &offset)
969 || strip_offset (src, &offset) == ep->to_rtx)
970 {
971 if (replace_p)
972 {
973 SET_DEST (old_set) = ep->to_rtx;
974 lra_update_insn_recog_data (insn);
975 return;
976 }
977 offset -= (ep->offset - ep->previous_offset);
978 src = plus_constant (Pmode, ep->to_rtx, offset);
979
980 /* First see if this insn remains valid when we
981 make the change. If not, keep the INSN_CODE
982 the same and let the constraint pass fit it
983 up. */
984 validate_change (insn, &SET_SRC (old_set), src, 1);
985 validate_change (insn, &SET_DEST (old_set),
986 ep->from_rtx, 1);
987 if (! apply_change_group ())
988 {
989 SET_SRC (old_set) = src;
990 SET_DEST (old_set) = ep->from_rtx;
991 }
992 lra_update_insn_recog_data (insn);
993 /* Add offset note for future updates. */
994 add_reg_note (insn, REG_EQUAL, copy_rtx (src));
995 return;
996 }
997 }
998 #endif
999
1000 /* This insn isn't serving a useful purpose. We delete it
1001 when REPLACE is set. */
1002 if (delete_p)
1003 lra_delete_dead_insn (insn);
1004 return;
1005 }
1006 } 904 }
1007 905
1008 /* We allow one special case which happens to work on all machines we 906 /* We allow one special case which happens to work on all machines we
1009 currently support: a single set with the source or a REG_EQUAL 907 currently support: a single set with the source or a REG_EQUAL
1010 note being a PLUS of an eliminable register and a constant. */ 908 note being a PLUS of an eliminable register and a constant. */
1107 if (static_id->operand[i].type != OP_IN 1005 if (static_id->operand[i].type != OP_IN
1108 && REG_P (orig_operand[i])) 1006 && REG_P (orig_operand[i]))
1109 { 1007 {
1110 /* If we are assigning to a hard register that can be 1008 /* If we are assigning to a hard register that can be
1111 eliminated, it must be as part of a PARALLEL, since 1009 eliminated, it must be as part of a PARALLEL, since
1112 the code above handles single SETs. This reg can not 1010 the code above handles single SETs. This reg cannot
1113 be longer eliminated -- it is forced by 1011 be longer eliminated -- it is forced by
1114 mark_not_eliminable. */ 1012 mark_not_eliminable. */
1115 for (ep = reg_eliminate; 1013 for (ep = reg_eliminate;
1116 ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; 1014 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
1117 ep++) 1015 ep++)
1143 /* If we had a move insn but now we don't, re-recognize it. 1041 /* If we had a move insn but now we don't, re-recognize it.
1144 This will cause spurious re-recognition if the old move had a 1042 This will cause spurious re-recognition if the old move had a
1145 PARALLEL since the new one still will, but we can't call 1043 PARALLEL since the new one still will, but we can't call
1146 single_set without having put new body into the insn and the 1044 single_set without having put new body into the insn and the
1147 re-recognition won't hurt in this rare case. */ 1045 re-recognition won't hurt in this rare case. */
1148 id = lra_update_insn_recog_data (insn); 1046 lra_update_insn_recog_data (insn);
1149 static_id = id->insn_static_data;
1150 } 1047 }
1151 1048
1152 /* Spill pseudos which are assigned to hard registers in SET. Add 1049 /* Spill pseudos which are assigned to hard registers in SET. Add
1153 affected insns for processing in the subsequent constraint 1050 affected insns for processing in the subsequent constraint
1154 pass. */ 1051 pass. */
1179 fprintf (lra_dump_file, " Spilling r%d(%d)\n", 1076 fprintf (lra_dump_file, " Spilling r%d(%d)\n",
1180 i, reg_renumber[i]); 1077 i, reg_renumber[i]);
1181 reg_renumber[i] = -1; 1078 reg_renumber[i] = -1;
1182 bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap); 1079 bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap);
1183 } 1080 }
1184 IOR_HARD_REG_SET (lra_no_alloc_regs, set); 1081 lra_no_alloc_regs |= set;
1185 for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) 1082 for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
1186 if (bitmap_bit_p (&to_process, INSN_UID (insn))) 1083 if (bitmap_bit_p (&to_process, INSN_UID (insn)))
1187 { 1084 {
1188 lra_push_insn (insn); 1085 lra_push_insn (insn);
1189 lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); 1086 lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1199 elimination offset changed. */ 1096 elimination offset changed. */
1200 static bool 1097 static bool
1201 update_reg_eliminate (bitmap insns_with_changed_offsets) 1098 update_reg_eliminate (bitmap insns_with_changed_offsets)
1202 { 1099 {
1203 bool prev, result; 1100 bool prev, result;
1204 struct lra_elim_table *ep, *ep1; 1101 class lra_elim_table *ep, *ep1;
1205 HARD_REG_SET temp_hard_reg_set; 1102 HARD_REG_SET temp_hard_reg_set;
1206 1103
1207 targetm.compute_frame_layout (); 1104 targetm.compute_frame_layout ();
1208 1105
1209 /* Clear self elimination offsets. */ 1106 /* Clear self elimination offsets. */
1234 if (lra_dump_file != NULL) 1131 if (lra_dump_file != NULL)
1235 fprintf (lra_dump_file, 1132 fprintf (lra_dump_file,
1236 " Elimination %d to %d is not possible anymore\n", 1133 " Elimination %d to %d is not possible anymore\n",
1237 ep->from, ep->to); 1134 ep->from, ep->to);
1238 /* If after processing RTL we decides that SP can be used as 1135 /* If after processing RTL we decides that SP can be used as
1239 a result of elimination, it can not be changed. */ 1136 a result of elimination, it cannot be changed. */
1240 gcc_assert ((ep->to_rtx != stack_pointer_rtx) 1137 gcc_assert ((ep->to_rtx != stack_pointer_rtx)
1241 || (ep->from < FIRST_PSEUDO_REGISTER 1138 || (ep->from < FIRST_PSEUDO_REGISTER
1242 && fixed_regs [ep->from])); 1139 && fixed_regs [ep->from]));
1243 /* Mark that is not eliminable anymore. */ 1140 /* Mark that is not eliminable anymore. */
1244 elimination_map[ep->from] = NULL; 1141 elimination_map[ep->from] = NULL;
1292 lra_update_reg_val_offset (lra_reg_info[ep->from].val, 1189 lra_update_reg_val_offset (lra_reg_info[ep->from].val,
1293 ep->offset - ep->previous_offset); 1190 ep->offset - ep->previous_offset);
1294 result = true; 1191 result = true;
1295 } 1192 }
1296 } 1193 }
1297 IOR_HARD_REG_SET (lra_no_alloc_regs, temp_hard_reg_set); 1194 lra_no_alloc_regs |= temp_hard_reg_set;
1298 AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set); 1195 eliminable_regset &= ~temp_hard_reg_set;
1299 spill_pseudos (temp_hard_reg_set); 1196 spill_pseudos (temp_hard_reg_set);
1300 return result; 1197 return result;
1301 } 1198 }
1302 1199
1303 /* Initialize the table of hard registers to eliminate. 1200 /* Initialize the table of hard registers to eliminate.
1304 Pre-condition: global flag frame_pointer_needed has been set before 1201 Pre-condition: global flag frame_pointer_needed has been set before
1305 calling this function. */ 1202 calling this function. */
1306 static void 1203 static void
1307 init_elim_table (void) 1204 init_elim_table (void)
1308 { 1205 {
1309 struct lra_elim_table *ep; 1206 class lra_elim_table *ep;
1310 bool value_p; 1207 bool value_p;
1311 const struct elim_table_1 *ep1; 1208 const struct elim_table_1 *ep1;
1312 1209
1313 if (!reg_eliminate) 1210 if (!reg_eliminate)
1314 reg_eliminate = XCNEWVEC (struct lra_elim_table, NUM_ELIMINABLE_REGS); 1211 reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS);
1315 1212
1316 memset (self_elim_offsets, 0, sizeof (self_elim_offsets)); 1213 memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
1317 /* Initiate member values which will be never changed. */ 1214 /* Initiate member values which will be never changed. */
1318 self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true; 1215 self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true;
1319 self_elim_table.previous_offset = 0; 1216 self_elim_table.previous_offset = 0;
1352 init_elimination (void) 1249 init_elimination (void)
1353 { 1250 {
1354 bool stop_to_sp_elimination_p; 1251 bool stop_to_sp_elimination_p;
1355 basic_block bb; 1252 basic_block bb;
1356 rtx_insn *insn; 1253 rtx_insn *insn;
1357 struct lra_elim_table *ep; 1254 class lra_elim_table *ep;
1358 1255
1359 init_elim_table (); 1256 init_elim_table ();
1360 FOR_EACH_BB_FN (bb, cfun) 1257 FOR_EACH_BB_FN (bb, cfun)
1361 { 1258 {
1362 curr_sp_change = 0; 1259 curr_sp_change = 0;
1386 /* Eliminate hard reg given by its location LOC. */ 1283 /* Eliminate hard reg given by its location LOC. */
1387 void 1284 void
1388 lra_eliminate_reg_if_possible (rtx *loc) 1285 lra_eliminate_reg_if_possible (rtx *loc)
1389 { 1286 {
1390 int regno; 1287 int regno;
1391 struct lra_elim_table *ep; 1288 class lra_elim_table *ep;
1392 1289
1393 lra_assert (REG_P (*loc)); 1290 lra_assert (REG_P (*loc));
1394 if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER 1291 if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
1395 || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)) 1292 || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
1396 return; 1293 return;
1412 insn as a move anymore. */ 1309 insn as a move anymore. */
1413 int icode = recog (PATTERN (insn), insn, 0); 1310 int icode = recog (PATTERN (insn), insn, 0);
1414 1311
1415 if (icode >= 0 && icode != INSN_CODE (insn)) 1312 if (icode >= 0 && icode != INSN_CODE (insn))
1416 { 1313 {
1314 if (INSN_CODE (insn) >= 0)
1315 /* Insn code is changed. It may change its operand type
1316 from IN to INOUT. Inform the subsequent assignment
1317 subpass about this situation. */
1318 check_and_force_assignment_correctness_p = true;
1417 INSN_CODE (insn) = icode; 1319 INSN_CODE (insn) = icode;
1418 lra_update_insn_recog_data (insn); 1320 lra_update_insn_recog_data (insn);
1419 } 1321 }
1420 lra_update_insn_regno_info (insn); 1322 lra_update_insn_regno_info (insn);
1421 lra_push_insn (insn); 1323 lra_push_insn (insn);
1430 lra_eliminate (bool final_p, bool first_p) 1332 lra_eliminate (bool final_p, bool first_p)
1431 { 1333 {
1432 unsigned int uid; 1334 unsigned int uid;
1433 bitmap_head insns_with_changed_offsets; 1335 bitmap_head insns_with_changed_offsets;
1434 bitmap_iterator bi; 1336 bitmap_iterator bi;
1435 struct lra_elim_table *ep; 1337 class lra_elim_table *ep;
1436 1338
1437 gcc_assert (! final_p || ! first_p); 1339 gcc_assert (! final_p || ! first_p);
1438 1340
1439 timevar_push (TV_LRA_ELIMINATE); 1341 timevar_push (TV_LRA_ELIMINATE);
1440 1342