comparison gcc/postreload.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
15:561a7518be6b 16:04ced10e8804
1 /* Perform simple optimizations to clean up the result of reload. 1 /* Perform simple optimizations to clean up the result of reload.
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 2 Copyright (C) 1987-2017 Free Software Foundation, Inc.
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4 2010, 2011 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
20 <http://www.gnu.org/licenses/>. */ 18 <http://www.gnu.org/licenses/>. */
21 19
22 #include "config.h" 20 #include "config.h"
23 #include "system.h" 21 #include "system.h"
24 #include "coretypes.h" 22 #include "coretypes.h"
25 #include "tm.h" 23 #include "backend.h"
26 24 #include "target.h"
27 #include "machmode.h"
28 #include "hard-reg-set.h"
29 #include "rtl.h" 25 #include "rtl.h"
26 #include "tree.h"
27 #include "predict.h"
28 #include "df.h"
29 #include "memmodel.h"
30 #include "tm_p.h" 30 #include "tm_p.h"
31 #include "obstack.h"
32 #include "insn-config.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "optabs.h" 31 #include "optabs.h"
37 #include "regs.h" 32 #include "regs.h"
38 #include "basic-block.h" 33 #include "emit-rtl.h"
34 #include "recog.h"
35
36 #include "cfgrtl.h"
37 #include "cfgbuild.h"
38 #include "cfgcleanup.h"
39 #include "reload.h" 39 #include "reload.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "cselib.h" 40 #include "cselib.h"
43 #include "diagnostic-core.h"
44 #include "except.h"
45 #include "tree.h"
46 #include "target.h"
47 #include "timevar.h"
48 #include "tree-pass.h" 41 #include "tree-pass.h"
49 #include "df.h"
50 #include "dbgcnt.h" 42 #include "dbgcnt.h"
51 43
52 static int reload_cse_noop_set_p (rtx); 44 static int reload_cse_noop_set_p (rtx);
53 static void reload_cse_simplify (rtx, rtx); 45 static bool reload_cse_simplify (rtx_insn *, rtx);
54 static void reload_cse_regs_1 (rtx); 46 static void reload_cse_regs_1 (void);
55 static int reload_cse_simplify_set (rtx, rtx); 47 static int reload_cse_simplify_set (rtx, rtx_insn *);
56 static int reload_cse_simplify_operands (rtx, rtx); 48 static int reload_cse_simplify_operands (rtx_insn *, rtx);
57 49
58 static void reload_combine (void); 50 static void reload_combine (void);
59 static void reload_combine_note_use (rtx *, rtx, int, rtx); 51 static void reload_combine_note_use (rtx *, rtx_insn *, int, rtx);
60 static void reload_combine_note_store (rtx, const_rtx, void *); 52 static void reload_combine_note_store (rtx, const_rtx, void *);
61 53
62 static bool reload_cse_move2add (rtx); 54 static bool reload_cse_move2add (rtx_insn *);
63 static void move2add_note_store (rtx, const_rtx, void *); 55 static void move2add_note_store (rtx, const_rtx, void *);
64 56
65 /* Call cse / combine like post-reload optimization phases. 57 /* Call cse / combine like post-reload optimization phases.
66 FIRST is the first instruction. */ 58 FIRST is the first instruction. */
67 void 59
68 reload_cse_regs (rtx first ATTRIBUTE_UNUSED) 60 static void
61 reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
69 { 62 {
70 bool moves_converted; 63 bool moves_converted;
71 reload_cse_regs_1 (first); 64 reload_cse_regs_1 ();
72 reload_combine (); 65 reload_combine ();
73 moves_converted = reload_cse_move2add (first); 66 moves_converted = reload_cse_move2add (first);
74 if (flag_expensive_optimizations) 67 if (flag_expensive_optimizations)
75 { 68 {
76 if (moves_converted) 69 if (moves_converted)
77 reload_combine (); 70 reload_combine ();
78 reload_cse_regs_1 (first); 71 reload_cse_regs_1 ();
79 } 72 }
80 } 73 }
81 74
82 /* See whether a single set SET is a noop. */ 75 /* See whether a single set SET is a noop. */
83 static int 76 static int
87 return 0; 80 return 0;
88 81
89 return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set)); 82 return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set));
90 } 83 }
91 84
92 /* Try to simplify INSN. */ 85 /* Try to simplify INSN. Return true if the CFG may have changed. */
93 static void 86 static bool
94 reload_cse_simplify (rtx insn, rtx testreg) 87 reload_cse_simplify (rtx_insn *insn, rtx testreg)
95 { 88 {
96 rtx body = PATTERN (insn); 89 rtx body = PATTERN (insn);
90 basic_block insn_bb = BLOCK_FOR_INSN (insn);
91 unsigned insn_bb_succs = EDGE_COUNT (insn_bb->succs);
92
93 /* If NO_FUNCTION_CSE has been set by the target, then we should not try
94 to cse function calls. */
95 if (NO_FUNCTION_CSE && CALL_P (insn))
96 return false;
97 97
98 if (GET_CODE (body) == SET) 98 if (GET_CODE (body) == SET)
99 { 99 {
100 int count = 0; 100 int count = 0;
101 101
106 this out, so it's safer to simplify before we delete. */ 106 this out, so it's safer to simplify before we delete. */
107 count += reload_cse_simplify_set (body, insn); 107 count += reload_cse_simplify_set (body, insn);
108 108
109 if (!count && reload_cse_noop_set_p (body)) 109 if (!count && reload_cse_noop_set_p (body))
110 { 110 {
111 rtx value = SET_DEST (body); 111 if (check_for_inc_dec (insn))
112 if (REG_P (value) 112 delete_insn_and_edges (insn);
113 && ! REG_FUNCTION_VALUE_P (value)) 113 /* We're done with this insn. */
114 value = 0; 114 goto done;
115 check_for_inc_dec (insn);
116 delete_insn_and_edges (insn);
117 return;
118 } 115 }
119 116
120 if (count > 0) 117 if (count > 0)
121 apply_change_group (); 118 apply_change_group ();
122 else 119 else
156 if (value) 153 if (value)
157 break; 154 break;
158 value = SET_DEST (part); 155 value = SET_DEST (part);
159 } 156 }
160 } 157 }
161 else if (GET_CODE (part) != CLOBBER) 158 else if (GET_CODE (part) != CLOBBER
159 && GET_CODE (part) != USE)
162 break; 160 break;
163 } 161 }
164 162
165 if (i < 0) 163 if (i < 0)
166 { 164 {
167 check_for_inc_dec (insn); 165 if (check_for_inc_dec (insn))
168 delete_insn_and_edges (insn); 166 delete_insn_and_edges (insn);
169 /* We're done with this insn. */ 167 /* We're done with this insn. */
170 return; 168 goto done;
171 } 169 }
172 170
173 /* It's not a no-op, but we can try to simplify it. */ 171 /* It's not a no-op, but we can try to simplify it. */
174 for (i = XVECLEN (body, 0) - 1; i >= 0; --i) 172 for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
175 if (GET_CODE (XVECEXP (body, 0, i)) == SET) 173 if (GET_CODE (XVECEXP (body, 0, i)) == SET)
178 if (count > 0) 176 if (count > 0)
179 apply_change_group (); 177 apply_change_group ();
180 else 178 else
181 reload_cse_simplify_operands (insn, testreg); 179 reload_cse_simplify_operands (insn, testreg);
182 } 180 }
181
182 done:
183 return (EDGE_COUNT (insn_bb->succs) != insn_bb_succs);
183 } 184 }
184 185
185 /* Do a very simple CSE pass over the hard registers. 186 /* Do a very simple CSE pass over the hard registers.
186 187
187 This function detects no-op moves where we happened to assign two 188 This function detects no-op moves where we happened to assign two
198 instruction to see whether the value is already available in a 199 instruction to see whether the value is already available in a
199 hard register. It then replaces the operand with the hard register 200 hard register. It then replaces the operand with the hard register
200 if possible, much like an optional reload would. */ 201 if possible, much like an optional reload would. */
201 202
202 static void 203 static void
203 reload_cse_regs_1 (rtx first) 204 reload_cse_regs_1 (void)
204 { 205 {
205 rtx insn; 206 bool cfg_changed = false;
206 rtx testreg = gen_rtx_REG (VOIDmode, -1); 207 basic_block bb;
208 rtx_insn *insn;
209 rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
207 210
208 cselib_init (CSELIB_RECORD_MEMORY); 211 cselib_init (CSELIB_RECORD_MEMORY);
209 init_alias_analysis (); 212 init_alias_analysis ();
210 213
211 for (insn = first; insn; insn = NEXT_INSN (insn)) 214 FOR_EACH_BB_FN (bb, cfun)
212 { 215 FOR_BB_INSNS (bb, insn)
213 if (INSN_P (insn)) 216 {
214 reload_cse_simplify (insn, testreg); 217 if (INSN_P (insn))
215 218 cfg_changed |= reload_cse_simplify (insn, testreg);
216 cselib_process_insn (insn); 219
217 } 220 cselib_process_insn (insn);
221 }
218 222
219 /* Clean up. */ 223 /* Clean up. */
220 end_alias_analysis (); 224 end_alias_analysis ();
221 cselib_finish (); 225 cselib_finish ();
226 if (cfg_changed)
227 cleanup_cfg (0);
222 } 228 }
223 229
224 /* Try to simplify a single SET instruction. SET is the set pattern. 230 /* Try to simplify a single SET instruction. SET is the set pattern.
225 INSN is the instruction it came from. 231 INSN is the instruction it came from.
226 This function only handles one case: if we set a register to a value 232 This function only handles one case: if we set a register to a value
227 which is not a register, we try to find that value in some other register 233 which is not a register, we try to find that value in some other register
228 and change the set into a register copy. */ 234 and change the set into a register copy. */
229 235
230 static int 236 static int
231 reload_cse_simplify_set (rtx set, rtx insn) 237 reload_cse_simplify_set (rtx set, rtx_insn *insn)
232 { 238 {
233 int did_change = 0; 239 int did_change = 0;
234 int dreg; 240 int dreg;
235 rtx src; 241 rtx src;
236 enum reg_class dclass; 242 reg_class_t dclass;
237 int old_cost; 243 int old_cost;
238 cselib_val *val; 244 cselib_val *val;
239 struct elt_loc_list *l; 245 struct elt_loc_list *l;
240 #ifdef LOAD_EXTEND_OP
241 enum rtx_code extend_op = UNKNOWN; 246 enum rtx_code extend_op = UNKNOWN;
242 #endif
243 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); 247 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
244 248
245 dreg = true_regnum (SET_DEST (set)); 249 dreg = true_regnum (SET_DEST (set));
246 if (dreg < 0) 250 if (dreg < 0)
247 return 0; 251 return 0;
250 if (side_effects_p (src) || true_regnum (src) >= 0) 254 if (side_effects_p (src) || true_regnum (src) >= 0)
251 return 0; 255 return 0;
252 256
253 dclass = REGNO_REG_CLASS (dreg); 257 dclass = REGNO_REG_CLASS (dreg);
254 258
255 #ifdef LOAD_EXTEND_OP
256 /* When replacing a memory with a register, we need to honor assumptions 259 /* When replacing a memory with a register, we need to honor assumptions
257 that combine made wrt the contents of sign bits. We'll do this by 260 that combine made wrt the contents of sign bits. We'll do this by
258 generating an extend instruction instead of a reg->reg copy. Thus 261 generating an extend instruction instead of a reg->reg copy. Thus
259 the destination must be a register that we can widen. */ 262 the destination must be a register that we can widen. */
260 if (MEM_P (src) 263 if (MEM_P (src)
261 && GET_MODE_BITSIZE (GET_MODE (src)) < BITS_PER_WORD 264 && (extend_op = load_extend_op (GET_MODE (src))) != UNKNOWN
262 && (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != UNKNOWN
263 && !REG_P (SET_DEST (set))) 265 && !REG_P (SET_DEST (set)))
264 return 0; 266 return 0;
265 #endif
266 267
267 val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode); 268 val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
268 if (! val) 269 if (! val)
269 return 0; 270 return 0;
270 271
273 old_cost = memory_move_cost (GET_MODE (src), dclass, true); 274 old_cost = memory_move_cost (GET_MODE (src), dclass, true);
274 else if (REG_P (src)) 275 else if (REG_P (src))
275 old_cost = register_move_cost (GET_MODE (src), 276 old_cost = register_move_cost (GET_MODE (src),
276 REGNO_REG_CLASS (REGNO (src)), dclass); 277 REGNO_REG_CLASS (REGNO (src)), dclass);
277 else 278 else
278 old_cost = rtx_cost (src, SET, speed); 279 old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
279 280
280 for (l = val->locs; l; l = l->next) 281 for (l = val->locs; l; l = l->next)
281 { 282 {
282 rtx this_rtx = l->loc; 283 rtx this_rtx = l->loc;
283 int this_cost; 284 int this_cost;
284 285
285 if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0)) 286 if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
286 { 287 {
287 #ifdef LOAD_EXTEND_OP
288 if (extend_op != UNKNOWN) 288 if (extend_op != UNKNOWN)
289 { 289 {
290 HOST_WIDE_INT this_val; 290 wide_int result;
291 291
292 /* ??? I'm lazy and don't wish to handle CONST_DOUBLE. Other 292 if (!CONST_SCALAR_INT_P (this_rtx))
293 constants, such as SYMBOL_REF, cannot be extended. */
294 if (!CONST_INT_P (this_rtx))
295 continue; 293 continue;
296 294
297 this_val = INTVAL (this_rtx);
298 switch (extend_op) 295 switch (extend_op)
299 { 296 {
300 case ZERO_EXTEND: 297 case ZERO_EXTEND:
301 this_val &= GET_MODE_MASK (GET_MODE (src)); 298 result = wide_int::from (rtx_mode_t (this_rtx,
299 GET_MODE (src)),
300 BITS_PER_WORD, UNSIGNED);
302 break; 301 break;
303 case SIGN_EXTEND: 302 case SIGN_EXTEND:
304 /* ??? In theory we're already extended. */ 303 result = wide_int::from (rtx_mode_t (this_rtx,
305 if (this_val == trunc_int_for_mode (this_val, GET_MODE (src))) 304 GET_MODE (src)),
306 break; 305 BITS_PER_WORD, SIGNED);
306 break;
307 default: 307 default:
308 gcc_unreachable (); 308 gcc_unreachable ();
309 } 309 }
310 this_rtx = GEN_INT (this_val); 310 this_rtx = immed_wide_int_const (result, word_mode);
311 } 311 }
312 #endif 312
313 this_cost = rtx_cost (this_rtx, SET, speed); 313 this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
314 } 314 }
315 else if (REG_P (this_rtx)) 315 else if (REG_P (this_rtx))
316 { 316 {
317 #ifdef LOAD_EXTEND_OP
318 if (extend_op != UNKNOWN) 317 if (extend_op != UNKNOWN)
319 { 318 {
320 this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx); 319 this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
321 this_cost = rtx_cost (this_rtx, SET, speed); 320 this_cost = set_src_cost (this_rtx, word_mode, speed);
322 } 321 }
323 else 322 else
324 #endif
325 this_cost = register_move_cost (GET_MODE (this_rtx), 323 this_cost = register_move_cost (GET_MODE (this_rtx),
326 REGNO_REG_CLASS (REGNO (this_rtx)), 324 REGNO_REG_CLASS (REGNO (this_rtx)),
327 dclass); 325 dclass);
328 } 326 }
329 else 327 else
334 if (this_cost < old_cost 332 if (this_cost < old_cost
335 || (this_cost == old_cost 333 || (this_cost == old_cost
336 && REG_P (this_rtx) 334 && REG_P (this_rtx)
337 && !REG_P (SET_SRC (set)))) 335 && !REG_P (SET_SRC (set))))
338 { 336 {
339 #ifdef LOAD_EXTEND_OP 337 if (extend_op != UNKNOWN
340 if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD 338 && REG_CAN_CHANGE_MODE_P (REGNO (SET_DEST (set)),
341 && extend_op != UNKNOWN 339 GET_MODE (SET_DEST (set)), word_mode))
342 #ifdef CANNOT_CHANGE_MODE_CLASS
343 && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
344 word_mode,
345 REGNO_REG_CLASS (REGNO (SET_DEST (set))))
346 #endif
347 )
348 { 340 {
349 rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set))); 341 rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
350 ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set)); 342 ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
351 validate_change (insn, &SET_DEST (set), wide_dest, 1); 343 validate_change (insn, &SET_DEST (set), wide_dest, 1);
352 } 344 }
353 #endif
354 345
355 validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1); 346 validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
356 old_cost = this_cost, did_change = 1; 347 old_cost = this_cost, did_change = 1;
357 } 348 }
358 } 349 }
370 "better" is in terms of '?' and '!' constraints. Among the remaining 361 "better" is in terms of '?' and '!' constraints. Among the remaining
371 alternatives, select the one which replaces most operands with 362 alternatives, select the one which replaces most operands with
372 hard registers. */ 363 hard registers. */
373 364
374 static int 365 static int
375 reload_cse_simplify_operands (rtx insn, rtx testreg) 366 reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
376 { 367 {
377 int i, j; 368 int i, j;
378 369
379 /* For each operand, all registers that are equivalent to it. */ 370 /* For each operand, all registers that are equivalent to it. */
380 HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS]; 371 HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
391 left as it is. */ 382 left as it is. */
392 int *op_alt_regno[MAX_RECOG_OPERANDS]; 383 int *op_alt_regno[MAX_RECOG_OPERANDS];
393 /* Array of alternatives, sorted in order of decreasing desirability. */ 384 /* Array of alternatives, sorted in order of decreasing desirability. */
394 int *alternative_order; 385 int *alternative_order;
395 386
396 extract_insn (insn); 387 extract_constrain_insn (insn);
397 388
398 if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0) 389 if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
399 return 0; 390 return 0;
400
401 /* Figure out which alternative currently matches. */
402 if (! constrain_operands (1))
403 fatal_insn_not_found (insn);
404 391
405 alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives); 392 alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
406 alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives); 393 alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
407 alternative_order = XALLOCAVEC (int, recog_data.n_alternatives); 394 alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
408 memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int)); 395 memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
416 rtx op; 403 rtx op;
417 404
418 CLEAR_HARD_REG_SET (equiv_regs[i]); 405 CLEAR_HARD_REG_SET (equiv_regs[i]);
419 406
420 /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem 407 /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem
421 right, so avoid the problem here. Likewise if we have a constant 408 right, so avoid the problem here. Similarly NOTE_INSN_DELETED_LABEL.
422 and the insn pattern doesn't tell us the mode we need. */ 409 Likewise if we have a constant and the insn pattern doesn't tell us
410 the mode we need. */
423 if (LABEL_P (recog_data.operand[i]) 411 if (LABEL_P (recog_data.operand[i])
412 || (NOTE_P (recog_data.operand[i])
413 && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
424 || (CONSTANT_P (recog_data.operand[i]) 414 || (CONSTANT_P (recog_data.operand[i])
425 && recog_data.operand_mode[i] == VOIDmode)) 415 && recog_data.operand_mode[i] == VOIDmode))
426 continue; 416 continue;
427 417
428 op = recog_data.operand[i]; 418 op = recog_data.operand[i];
429 #ifdef LOAD_EXTEND_OP 419 if (MEM_P (op) && load_extend_op (GET_MODE (op)) != UNKNOWN)
430 if (MEM_P (op)
431 && GET_MODE_BITSIZE (GET_MODE (op)) < BITS_PER_WORD
432 && LOAD_EXTEND_OP (GET_MODE (op)) != UNKNOWN)
433 { 420 {
434 rtx set = single_set (insn); 421 rtx set = single_set (insn);
435 422
436 /* We might have multiple sets, some of which do implicit 423 /* We might have multiple sets, some of which do implicit
437 extension. Punt on this for now. */ 424 extension. Punt on this for now. */
444 else if (MEM_P (SET_DEST (set)) 431 else if (MEM_P (SET_DEST (set))
445 || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART 432 || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART
446 || GET_CODE (SET_SRC (set)) == ZERO_EXTEND 433 || GET_CODE (SET_SRC (set)) == ZERO_EXTEND
447 || GET_CODE (SET_SRC (set)) == SIGN_EXTEND) 434 || GET_CODE (SET_SRC (set)) == SIGN_EXTEND)
448 ; /* Continue ordinary processing. */ 435 ; /* Continue ordinary processing. */
449 #ifdef CANNOT_CHANGE_MODE_CLASS
450 /* If the register cannot change mode to word_mode, it follows that 436 /* If the register cannot change mode to word_mode, it follows that
451 it cannot have been used in word_mode. */ 437 it cannot have been used in word_mode. */
452 else if (REG_P (SET_DEST (set)) 438 else if (REG_P (SET_DEST (set))
453 && CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)), 439 && !REG_CAN_CHANGE_MODE_P (REGNO (SET_DEST (set)),
454 word_mode, 440 GET_MODE (SET_DEST (set)),
455 REGNO_REG_CLASS (REGNO (SET_DEST (set))))) 441 word_mode))
456 ; /* Continue ordinary processing. */ 442 ; /* Continue ordinary processing. */
457 #endif
458 /* If this is a straight load, make the extension explicit. */ 443 /* If this is a straight load, make the extension explicit. */
459 else if (REG_P (SET_DEST (set)) 444 else if (REG_P (SET_DEST (set))
460 && recog_data.n_operands == 2 445 && recog_data.n_operands == 2
461 && SET_SRC (set) == op 446 && SET_SRC (set) == op
462 && SET_DEST (set) == recog_data.operand[1-i]) 447 && SET_DEST (set) == recog_data.operand[1-i])
463 { 448 {
464 validate_change (insn, recog_data.operand_loc[i], 449 validate_change (insn, recog_data.operand_loc[i],
465 gen_rtx_fmt_e (LOAD_EXTEND_OP (GET_MODE (op)), 450 gen_rtx_fmt_e (load_extend_op (GET_MODE (op)),
466 word_mode, op), 451 word_mode, op),
467 1); 452 1);
468 validate_change (insn, recog_data.operand_loc[1-i], 453 validate_change (insn, recog_data.operand_loc[1-i],
469 gen_rtx_REG (word_mode, REGNO (SET_DEST (set))), 454 gen_rtx_REG (word_mode, REGNO (SET_DEST (set))),
470 1); 455 1);
475 else 460 else
476 /* ??? There might be arithmetic operations with memory that are 461 /* ??? There might be arithmetic operations with memory that are
477 safe to optimize, but is it worth the trouble? */ 462 safe to optimize, but is it worth the trouble? */
478 continue; 463 continue;
479 } 464 }
480 #endif /* LOAD_EXTEND_OP */ 465
481 if (side_effects_p (op)) 466 if (side_effects_p (op))
482 continue; 467 continue;
483 v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode); 468 v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
484 if (! v) 469 if (! v)
485 continue; 470 continue;
487 for (l = v->locs; l; l = l->next) 472 for (l = v->locs; l; l = l->next)
488 if (REG_P (l->loc)) 473 if (REG_P (l->loc))
489 SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc)); 474 SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
490 } 475 }
491 476
477 alternative_mask preferred = get_preferred_alternatives (insn);
492 for (i = 0; i < recog_data.n_operands; i++) 478 for (i = 0; i < recog_data.n_operands; i++)
493 { 479 {
494 enum machine_mode mode; 480 machine_mode mode;
495 int regno; 481 int regno;
496 const char *p; 482 const char *p;
497 483
498 op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives); 484 op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
499 for (j = 0; j < recog_data.n_alternatives; j++) 485 for (j = 0; j < recog_data.n_alternatives; j++)
529 enum reg_class rclass = NO_REGS; 515 enum reg_class rclass = NO_REGS;
530 516
531 if (! TEST_HARD_REG_BIT (equiv_regs[i], regno)) 517 if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
532 continue; 518 continue;
533 519
534 SET_REGNO_RAW (testreg, regno); 520 set_mode_and_regno (testreg, mode, regno);
535 PUT_MODE (testreg, mode);
536 521
537 /* We found a register equal to this operand. Now look for all 522 /* We found a register equal to this operand. Now look for all
538 alternatives that can accept this register and have not been 523 alternatives that can accept this register and have not been
539 assigned a register they can use yet. */ 524 assigned a register they can use yet. */
540 j = 0; 525 j = 0;
543 { 528 {
544 char c = *p; 529 char c = *p;
545 530
546 switch (c) 531 switch (c)
547 { 532 {
548 case '=': case '+': case '?': 533 case 'g':
549 case '#': case '&': case '!': 534 rclass = reg_class_subunion[rclass][GENERAL_REGS];
550 case '*': case '%':
551 case '0': case '1': case '2': case '3': case '4':
552 case '5': case '6': case '7': case '8': case '9':
553 case '<': case '>': case 'V': case 'o':
554 case 'E': case 'F': case 'G': case 'H':
555 case 's': case 'i': case 'n':
556 case 'I': case 'J': case 'K': case 'L':
557 case 'M': case 'N': case 'O': case 'P':
558 case 'p': case 'X': case TARGET_MEM_CONSTRAINT:
559 /* These don't say anything we care about. */
560 break;
561
562 case 'g': case 'r':
563 rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS];
564 break; 535 break;
565 536
566 default: 537 default:
567 rclass 538 rclass
568 = (reg_class_subunion 539 = (reg_class_subunion
569 [(int) rclass] 540 [rclass]
570 [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); 541 [reg_class_for_constraint (lookup_constraint (p))]);
571 break; 542 break;
572 543
573 case ',': case '\0': 544 case ',': case '\0':
574 /* See if REGNO fits this alternative, and set it up as the 545 /* See if REGNO fits this alternative, and set it up as the
575 replacement register if we don't have one for this 546 replacement register if we don't have one for this
576 alternative yet and the operand being replaced is not 547 alternative yet and the operand being replaced is not
577 a cheap CONST_INT. */ 548 a cheap CONST_INT. */
578 if (op_alt_regno[i][j] == -1 549 if (op_alt_regno[i][j] == -1
579 && recog_data.alternative_enabled_p[j] 550 && TEST_BIT (preferred, j)
580 && reg_fits_class_p (testreg, rclass, 0, mode) 551 && reg_fits_class_p (testreg, rclass, 0, mode)
581 && (!CONST_INT_P (recog_data.operand[i]) 552 && (!CONST_INT_P (recog_data.operand[i])
582 || (rtx_cost (recog_data.operand[i], SET, 553 || (set_src_cost (recog_data.operand[i], mode,
583 optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn))) 554 optimize_bb_for_speed_p
584 > rtx_cost (testreg, SET, 555 (BLOCK_FOR_INSN (insn)))
585 optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))))) 556 > set_src_cost (testreg, mode,
557 optimize_bb_for_speed_p
558 (BLOCK_FOR_INSN (insn))))))
586 { 559 {
587 alternative_nregs[j]++; 560 alternative_nregs[j]++;
588 op_alt_regno[i][j] = regno; 561 op_alt_regno[i][j] = regno;
589 } 562 }
590 j++; 563 j++;
611 for (i = 0; i < recog_data.n_alternatives - 1; i++) 584 for (i = 0; i < recog_data.n_alternatives - 1; i++)
612 { 585 {
613 int best = i; 586 int best = i;
614 int best_reject = alternative_reject[alternative_order[i]]; 587 int best_reject = alternative_reject[alternative_order[i]];
615 int best_nregs = alternative_nregs[alternative_order[i]]; 588 int best_nregs = alternative_nregs[alternative_order[i]];
616 int tmp;
617 589
618 for (j = i + 1; j < recog_data.n_alternatives; j++) 590 for (j = i + 1; j < recog_data.n_alternatives; j++)
619 { 591 {
620 int this_reject = alternative_reject[alternative_order[j]]; 592 int this_reject = alternative_reject[alternative_order[j]];
621 int this_nregs = alternative_nregs[alternative_order[j]]; 593 int this_nregs = alternative_nregs[alternative_order[j]];
627 best_reject = this_reject; 599 best_reject = this_reject;
628 best_nregs = this_nregs; 600 best_nregs = this_nregs;
629 } 601 }
630 } 602 }
631 603
632 tmp = alternative_order[best]; 604 std::swap (alternative_order[best], alternative_order[i]);
633 alternative_order[best] = alternative_order[i];
634 alternative_order[i] = tmp;
635 } 605 }
636 606
637 /* Substitute the operands as determined by op_alt_regno for the best 607 /* Substitute the operands as determined by op_alt_regno for the best
638 alternative. */ 608 alternative. */
639 j = alternative_order[0]; 609 j = alternative_order[0];
640 610
641 for (i = 0; i < recog_data.n_operands; i++) 611 for (i = 0; i < recog_data.n_operands; i++)
642 { 612 {
643 enum machine_mode mode = recog_data.operand_mode[i]; 613 machine_mode mode = recog_data.operand_mode[i];
644 if (op_alt_regno[i][j] == -1) 614 if (op_alt_regno[i][j] == -1)
645 continue; 615 continue;
646 616
647 validate_change (insn, recog_data.operand_loc[i], 617 validate_change (insn, recog_data.operand_loc[i],
648 gen_rtx_REG (mode, op_alt_regno[i][j]), 1); 618 gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
649 } 619 }
650 620
651 for (i = recog_data.n_dups - 1; i >= 0; i--) 621 for (i = recog_data.n_dups - 1; i >= 0; i--)
652 { 622 {
653 int op = recog_data.dup_num[i]; 623 int op = recog_data.dup_num[i];
654 enum machine_mode mode = recog_data.operand_mode[op]; 624 machine_mode mode = recog_data.operand_mode[op];
655 625
656 if (op_alt_regno[op][j] == -1) 626 if (op_alt_regno[op][j] == -1)
657 continue; 627 continue;
658 628
659 validate_change (insn, recog_data.dup_loc[i], 629 validate_change (insn, recog_data.dup_loc[i],
674 644
675 /* Describes a recorded use of a register. */ 645 /* Describes a recorded use of a register. */
676 struct reg_use 646 struct reg_use
677 { 647 {
678 /* The insn where a register has been used. */ 648 /* The insn where a register has been used. */
679 rtx insn; 649 rtx_insn *insn;
680 /* Points to the memory reference enclosing the use, if any, NULL_RTX 650 /* Points to the memory reference enclosing the use, if any, NULL_RTX
681 otherwise. */ 651 otherwise. */
682 rtx containing_mem; 652 rtx containing_mem;
683 /* Location of the register withing INSN. */ 653 /* Location of the register within INSN. */
684 rtx *usep; 654 rtx *usep;
685 /* The reverse uid of the insn. */ 655 /* The reverse uid of the insn. */
686 int ruid; 656 int ruid;
687 }; 657 };
688 658
772 /* Called when we are about to rescan a previously encountered insn with 742 /* Called when we are about to rescan a previously encountered insn with
773 reload_combine_note_use after modifying some part of it. This clears all 743 reload_combine_note_use after modifying some part of it. This clears all
774 information about uses in that particular insn. */ 744 information about uses in that particular insn. */
775 745
776 static void 746 static void
777 reload_combine_purge_insn_uses (rtx insn) 747 reload_combine_purge_insn_uses (rtx_insn *insn)
778 { 748 {
779 unsigned i; 749 unsigned i;
780 750
781 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 751 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
782 { 752 {
857 the destination register of the add insn; REPLACEMENT is the 827 the destination register of the add insn; REPLACEMENT is the
858 SET_SRC of the add. FROM and TO specify the range in which we 828 SET_SRC of the add. FROM and TO specify the range in which we
859 should make this change on debug insns. */ 829 should make this change on debug insns. */
860 830
861 static void 831 static void
862 fixup_debug_insns (rtx reg, rtx replacement, rtx from, rtx to) 832 fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
863 { 833 {
864 rtx insn; 834 rtx_insn *insn;
865 for (insn = from; insn != to; insn = NEXT_INSN (insn)) 835 for (insn = from; insn != to; insn = NEXT_INSN (insn))
866 { 836 {
867 rtx t; 837 rtx t;
868 838
869 if (!DEBUG_INSN_P (insn)) 839 if (!DEBUG_INSN_P (insn))
880 true if we made the replacement. */ 850 true if we made the replacement. */
881 851
882 static bool 852 static bool
883 try_replace_in_use (struct reg_use *use, rtx reg, rtx src) 853 try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
884 { 854 {
885 rtx use_insn = use->insn; 855 rtx_insn *use_insn = use->insn;
886 rtx mem = use->containing_mem; 856 rtx mem = use->containing_mem;
887 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn)); 857 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
888 858
889 if (mem != NULL_RTX) 859 if (mem != NULL_RTX)
890 { 860 {
914 && GET_CODE (SET_SRC (new_set)) == PLUS 884 && GET_CODE (SET_SRC (new_set)) == PLUS
915 && REG_P (XEXP (SET_SRC (new_set), 0)) 885 && REG_P (XEXP (SET_SRC (new_set), 0))
916 && CONSTANT_P (XEXP (SET_SRC (new_set), 1))) 886 && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
917 { 887 {
918 rtx new_src; 888 rtx new_src;
919 int old_cost = rtx_cost (SET_SRC (new_set), SET, speed); 889 machine_mode mode = GET_MODE (SET_DEST (new_set));
890 int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
920 891
921 gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg)); 892 gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
922 new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src); 893 new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
923 894
924 if (rtx_cost (new_src, SET, speed) <= old_cost 895 if (set_src_cost (new_src, mode, speed) <= old_cost
925 && validate_change (use_insn, &SET_SRC (new_set), 896 && validate_change (use_insn, &SET_SRC (new_set),
926 new_src, 0)) 897 new_src, 0))
927 return true; 898 return true;
928 } 899 }
929 } 900 }
935 in an address. 906 in an address.
936 Return true if no further processing is needed on INSN; false if it wasn't 907 Return true if no further processing is needed on INSN; false if it wasn't
937 recognized and should be handled normally. */ 908 recognized and should be handled normally. */
938 909
939 static bool 910 static bool
940 reload_combine_recognize_const_pattern (rtx insn) 911 reload_combine_recognize_const_pattern (rtx_insn *insn)
941 { 912 {
942 int from_ruid = reload_combine_ruid; 913 int from_ruid = reload_combine_ruid;
943 rtx set, pat, reg, src, addreg; 914 rtx set, pat, reg, src, addreg;
944 unsigned int regno; 915 unsigned int regno;
945 struct reg_use *use; 916 struct reg_use *use;
946 bool must_move_add; 917 bool must_move_add;
947 rtx add_moved_after_insn = NULL_RTX; 918 rtx_insn *add_moved_after_insn = NULL;
948 int add_moved_after_ruid = 0; 919 int add_moved_after_ruid = 0;
949 int clobbered_regno = -1; 920 int clobbered_regno = -1;
950 921
951 set = single_set (insn); 922 set = single_set (insn);
952 if (set == NULL_RTX) 923 if (set == NULL_RTX)
953 return false; 924 return false;
954 925
955 reg = SET_DEST (set); 926 reg = SET_DEST (set);
956 src = SET_SRC (set); 927 src = SET_SRC (set);
957 if (!REG_P (reg) 928 if (!REG_P (reg)
958 || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1 929 || REG_NREGS (reg) != 1
959 || GET_MODE (reg) != Pmode 930 || GET_MODE (reg) != Pmode
960 || reg == stack_pointer_rtx) 931 || reg == stack_pointer_rtx)
961 return false; 932 return false;
962 933
963 regno = REGNO (reg); 934 regno = REGNO (reg);
998 from_ruid = use->ruid; 969 from_ruid = use->ruid;
999 970
1000 if (use && GET_MODE (*use->usep) == Pmode) 971 if (use && GET_MODE (*use->usep) == Pmode)
1001 { 972 {
1002 bool delete_add = false; 973 bool delete_add = false;
1003 rtx use_insn = use->insn; 974 rtx_insn *use_insn = use->insn;
1004 int use_ruid = use->ruid; 975 int use_ruid = use->ruid;
1005 976
1006 /* Avoid moving the add insn past a jump. */ 977 /* Avoid moving the add insn past a jump. */
1007 if (must_move_add && use_ruid <= last_jump_ruid) 978 if (must_move_add && use_ruid <= last_jump_ruid)
1008 break; 979 break;
1011 it past a real set of this hard reg. */ 982 it past a real set of this hard reg. */
1012 if (must_move_add && clobbered_regno >= 0 983 if (must_move_add && clobbered_regno >= 0
1013 && reg_state[clobbered_regno].real_store_ruid >= use_ruid) 984 && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1014 break; 985 break;
1015 986
1016 #ifdef HAVE_cc0
1017 /* Do not separate cc0 setter and cc0 user on HAVE_cc0 targets. */ 987 /* Do not separate cc0 setter and cc0 user on HAVE_cc0 targets. */
1018 if (must_move_add && sets_cc0_p (PATTERN (use_insn))) 988 if (HAVE_cc0 && must_move_add && sets_cc0_p (PATTERN (use_insn)))
1019 break; 989 break;
1020 #endif
1021 990
1022 gcc_assert (reg_state[regno].store_ruid <= use_ruid); 991 gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1023 /* Avoid moving a use of ADDREG past a point where it is stored. */ 992 /* Avoid moving a use of ADDREG past a point where it is stored. */
1024 if (reg_state[REGNO (addreg)].store_ruid > use_ruid) 993 if (reg_state[REGNO (addreg)].store_ruid > use_ruid)
1025 break; 994 break;
1079 /* Called by reload_combine when scanning INSN. Try to detect a pattern we 1048 /* Called by reload_combine when scanning INSN. Try to detect a pattern we
1080 can handle and improve. Return true if no further processing is needed on 1049 can handle and improve. Return true if no further processing is needed on
1081 INSN; false if it wasn't recognized and should be handled normally. */ 1050 INSN; false if it wasn't recognized and should be handled normally. */
1082 1051
1083 static bool 1052 static bool
1084 reload_combine_recognize_pattern (rtx insn) 1053 reload_combine_recognize_pattern (rtx_insn *insn)
1085 { 1054 {
1086 rtx set, reg, src; 1055 rtx set, reg, src;
1087 unsigned int regno;
1088 1056
1089 set = single_set (insn); 1057 set = single_set (insn);
1090 if (set == NULL_RTX) 1058 if (set == NULL_RTX)
1091 return false; 1059 return false;
1092 1060
1093 reg = SET_DEST (set); 1061 reg = SET_DEST (set);
1094 src = SET_SRC (set); 1062 src = SET_SRC (set);
1095 if (!REG_P (reg) 1063 if (!REG_P (reg) || REG_NREGS (reg) != 1)
1096 || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1)
1097 return false; 1064 return false;
1098 1065
1099 regno = REGNO (reg); 1066 unsigned int regno = REGNO (reg);
1067 machine_mode mode = GET_MODE (reg);
1068
1069 if (reg_state[regno].use_index < 0
1070 || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1071 return false;
1072
1073 for (int i = reg_state[regno].use_index;
1074 i < RELOAD_COMBINE_MAX_USES; i++)
1075 {
1076 struct reg_use *use = reg_state[regno].reg_use + i;
1077 if (GET_MODE (*use->usep) != mode)
1078 return false;
1079 }
1100 1080
1101 /* Look for (set (REGX) (CONST_INT)) 1081 /* Look for (set (REGX) (CONST_INT))
1102 (set (REGX) (PLUS (REGX) (REGY))) 1082 (set (REGX) (PLUS (REGX) (REGY)))
1103 ... 1083 ...
1104 ... (MEM (REGX)) ... 1084 ... (MEM (REGX)) ...
1116 && reg_state[regno].all_offsets_match 1096 && reg_state[regno].all_offsets_match
1117 && last_index_reg != -1 1097 && last_index_reg != -1
1118 && REG_P (XEXP (src, 1)) 1098 && REG_P (XEXP (src, 1))
1119 && rtx_equal_p (XEXP (src, 0), reg) 1099 && rtx_equal_p (XEXP (src, 0), reg)
1120 && !rtx_equal_p (XEXP (src, 1), reg) 1100 && !rtx_equal_p (XEXP (src, 1), reg)
1121 && reg_state[regno].use_index >= 0
1122 && reg_state[regno].use_index < RELOAD_COMBINE_MAX_USES
1123 && last_label_ruid < reg_state[regno].use_ruid) 1101 && last_label_ruid < reg_state[regno].use_ruid)
1124 { 1102 {
1125 rtx base = XEXP (src, 1); 1103 rtx base = XEXP (src, 1);
1126 rtx prev = prev_nonnote_nondebug_insn (insn); 1104 rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1127 rtx prev_set = prev ? single_set (prev) : NULL_RTX; 1105 rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1128 rtx index_reg = NULL_RTX; 1106 rtx index_reg = NULL_RTX;
1129 rtx reg_sum = NULL_RTX; 1107 rtx reg_sum = NULL_RTX;
1130 int i; 1108 int i;
1131 1109
1153 && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES 1131 && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1154 && reg_state[i].store_ruid <= reg_state[regno].use_ruid 1132 && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1155 && (call_used_regs[i] || df_regs_ever_live_p (i)) 1133 && (call_used_regs[i] || df_regs_ever_live_p (i))
1156 && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM) 1134 && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1157 && !fixed_regs[i] && !global_regs[i] 1135 && !fixed_regs[i] && !global_regs[i]
1158 && hard_regno_nregs[i][GET_MODE (reg)] == 1 1136 && hard_regno_nregs (i, GET_MODE (reg)) == 1
1159 && targetm.hard_regno_scratch_ok (i)) 1137 && targetm.hard_regno_scratch_ok (i))
1160 { 1138 {
1161 index_reg = gen_rtx_REG (GET_MODE (reg), i); 1139 index_reg = gen_rtx_REG (GET_MODE (reg), i);
1162 reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base); 1140 reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1163 break; 1141 break;
1214 fixup_debug_insns (reg, reg_sum, insn, lowest_ruid->insn); 1192 fixup_debug_insns (reg, reg_sum, insn, lowest_ruid->insn);
1215 1193
1216 /* Delete the reg-reg addition. */ 1194 /* Delete the reg-reg addition. */
1217 delete_insn (insn); 1195 delete_insn (insn);
1218 1196
1219 if (reg_state[regno].offset != const0_rtx) 1197 if (reg_state[regno].offset != const0_rtx
1220 /* Previous REG_EQUIV / REG_EQUAL notes for PREV 1198 /* Previous REG_EQUIV / REG_EQUAL notes for PREV
1221 are now invalid. */ 1199 are now invalid. */
1222 remove_reg_equal_equiv_notes (prev); 1200 && remove_reg_equal_equiv_notes (prev))
1201 df_notes_rescan (prev);
1223 1202
1224 reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES; 1203 reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
1225 return true; 1204 return true;
1226 } 1205 }
1227 } 1206 }
1230 } 1209 }
1231 1210
1232 static void 1211 static void
1233 reload_combine (void) 1212 reload_combine (void)
1234 { 1213 {
1235 rtx insn, prev; 1214 rtx_insn *insn, *prev;
1236 basic_block bb; 1215 basic_block bb;
1237 unsigned int r; 1216 unsigned int r;
1238 int min_labelno, n_labels; 1217 int min_labelno, n_labels;
1239 HARD_REG_SET ever_live_at_start, *label_live; 1218 HARD_REG_SET ever_live_at_start, *label_live;
1240 1219
1269 min_labelno = get_first_label_num (); 1248 min_labelno = get_first_label_num ();
1270 n_labels = max_label_num () - min_labelno; 1249 n_labels = max_label_num () - min_labelno;
1271 label_live = XNEWVEC (HARD_REG_SET, n_labels); 1250 label_live = XNEWVEC (HARD_REG_SET, n_labels);
1272 CLEAR_HARD_REG_SET (ever_live_at_start); 1251 CLEAR_HARD_REG_SET (ever_live_at_start);
1273 1252
1274 FOR_EACH_BB_REVERSE (bb) 1253 FOR_EACH_BB_REVERSE_FN (bb, cfun)
1275 { 1254 {
1276 insn = BB_HEAD (bb); 1255 insn = BB_HEAD (bb);
1277 if (LABEL_P (insn)) 1256 if (LABEL_P (insn))
1278 { 1257 {
1279 HARD_REG_SET live; 1258 HARD_REG_SET live;
1309 information we have would be costly, so we just note where the label 1288 information we have would be costly, so we just note where the label
1310 is and then later disable any optimization that would cross it. */ 1289 is and then later disable any optimization that would cross it. */
1311 if (LABEL_P (insn)) 1290 if (LABEL_P (insn))
1312 last_label_ruid = reload_combine_ruid; 1291 last_label_ruid = reload_combine_ruid;
1313 else if (BARRIER_P (insn)) 1292 else if (BARRIER_P (insn))
1293 {
1294 /* Crossing a barrier resets all the use information. */
1295 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1296 if (! fixed_regs[r])
1297 reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1298 }
1299 else if (INSN_P (insn) && volatile_insn_p (PATTERN (insn)))
1300 /* Optimizations across insns being marked as volatile must be
1301 prevented. All the usage information is invalidated
1302 here. */
1314 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 1303 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1315 if (! fixed_regs[r]) 1304 if (! fixed_regs[r]
1316 reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; 1305 && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1306 reg_state[r].use_index = -1;
1317 1307
1318 if (! NONDEBUG_INSN_P (insn)) 1308 if (! NONDEBUG_INSN_P (insn))
1319 continue; 1309 continue;
1320 1310
1321 reload_combine_ruid++; 1311 reload_combine_ruid++;
1331 note_stores (PATTERN (insn), reload_combine_note_store, NULL); 1321 note_stores (PATTERN (insn), reload_combine_note_store, NULL);
1332 1322
1333 if (CALL_P (insn)) 1323 if (CALL_P (insn))
1334 { 1324 {
1335 rtx link; 1325 rtx link;
1326 HARD_REG_SET used_regs;
1327
1328 get_call_reg_set_usage (insn, &used_regs, call_used_reg_set);
1336 1329
1337 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 1330 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1338 if (call_used_regs[r]) 1331 if (TEST_HARD_REG_BIT (used_regs, r))
1339 { 1332 {
1340 reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; 1333 reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1341 reg_state[r].store_ruid = reload_combine_ruid; 1334 reg_state[r].store_ruid = reload_combine_ruid;
1342 } 1335 }
1343 1336
1344 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; 1337 for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1345 link = XEXP (link, 1)) 1338 link = XEXP (link, 1))
1346 { 1339 {
1347 rtx usage_rtx = XEXP (XEXP (link, 0), 0); 1340 rtx setuse = XEXP (link, 0);
1348 if (REG_P (usage_rtx)) 1341 rtx usage_rtx = XEXP (setuse, 0);
1342 if ((GET_CODE (setuse) == USE || GET_CODE (setuse) == CLOBBER)
1343 && REG_P (usage_rtx))
1349 { 1344 {
1350 unsigned int i; 1345 unsigned int end_regno = END_REGNO (usage_rtx);
1351 unsigned int start_reg = REGNO (usage_rtx); 1346 for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1352 unsigned int num_regs
1353 = hard_regno_nregs[start_reg][GET_MODE (usage_rtx)];
1354 unsigned int end_reg = start_reg + num_regs - 1;
1355 for (i = start_reg; i <= end_reg; i++)
1356 if (GET_CODE (XEXP (link, 0)) == CLOBBER) 1347 if (GET_CODE (XEXP (link, 0)) == CLOBBER)
1357 { 1348 {
1358 reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; 1349 reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
1359 reg_state[i].store_ruid = reload_combine_ruid; 1350 reg_state[i].store_ruid = reload_combine_ruid;
1360 } 1351 }
1362 reg_state[i].use_index = -1; 1353 reg_state[i].use_index = -1;
1363 } 1354 }
1364 } 1355 }
1365 } 1356 }
1366 1357
1367 if (control_flow_insn && GET_CODE (PATTERN (insn)) != RETURN) 1358 if (control_flow_insn && !ANY_RETURN_P (PATTERN (insn)))
1368 { 1359 {
1369 /* Non-spill registers might be used at the call destination in 1360 /* Non-spill registers might be used at the call destination in
1370 some unknown fashion, so we have to mark the unknown use. */ 1361 some unknown fashion, so we have to mark the unknown use. */
1371 HARD_REG_SET *live; 1362 HARD_REG_SET *live;
1372 1363
1373 if ((condjump_p (insn) || condjump_in_parallel_p (insn)) 1364 if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1374 && JUMP_LABEL (insn)) 1365 && JUMP_LABEL (insn))
1375 live = &LABEL_LIVE (JUMP_LABEL (insn)); 1366 {
1367 if (ANY_RETURN_P (JUMP_LABEL (insn)))
1368 live = NULL;
1369 else
1370 live = &LABEL_LIVE (JUMP_LABEL (insn));
1371 }
1376 else 1372 else
1377 live = &ever_live_at_start; 1373 live = &ever_live_at_start;
1378 1374
1379 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 1375 if (live)
1380 if (TEST_HARD_REG_BIT (*live, r)) 1376 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1381 reg_state[r].use_index = -1; 1377 if (TEST_HARD_REG_BIT (*live, r))
1378 reg_state[r].use_index = -1;
1382 } 1379 }
1383 1380
1384 reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid, 1381 reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1385 NULL_RTX); 1382 NULL_RTX);
1386 1383
1406 static void 1403 static void
1407 reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED) 1404 reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1408 { 1405 {
1409 int regno = 0; 1406 int regno = 0;
1410 int i; 1407 int i;
1411 enum machine_mode mode = GET_MODE (dst); 1408 machine_mode mode = GET_MODE (dst);
1412 1409
1413 if (GET_CODE (dst) == SUBREG) 1410 if (GET_CODE (dst) == SUBREG)
1414 { 1411 {
1415 regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)), 1412 regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1416 GET_MODE (SUBREG_REG (dst)), 1413 GET_MODE (SUBREG_REG (dst)),
1426 dst = XEXP (dst, 0); 1423 dst = XEXP (dst, 0);
1427 if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC 1424 if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1428 || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC 1425 || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1429 || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY) 1426 || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1430 { 1427 {
1431 regno = REGNO (XEXP (dst, 0)); 1428 unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1432 mode = GET_MODE (XEXP (dst, 0)); 1429 for (unsigned int i = REGNO (XEXP (dst, 0)); i < end_regno; ++i)
1433 for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--)
1434 { 1430 {
1435 /* We could probably do better, but for now mark the register 1431 /* We could probably do better, but for now mark the register
1436 as used in an unknown fashion and set/clobbered at this 1432 as used in an unknown fashion and set/clobbered at this
1437 insn. */ 1433 insn. */
1438 reg_state[i].use_index = -1; 1434 reg_state[i].use_index = -1;
1452 careful with registers / register parts that are not full words. 1448 careful with registers / register parts that are not full words.
1453 Similarly for ZERO_EXTRACT. */ 1449 Similarly for ZERO_EXTRACT. */
1454 if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT 1450 if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1455 || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART) 1451 || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1456 { 1452 {
1457 for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--) 1453 for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1458 { 1454 {
1459 reg_state[i].use_index = -1; 1455 reg_state[i].use_index = -1;
1460 reg_state[i].store_ruid = reload_combine_ruid; 1456 reg_state[i].store_ruid = reload_combine_ruid;
1461 reg_state[i].real_store_ruid = reload_combine_ruid; 1457 reg_state[i].real_store_ruid = reload_combine_ruid;
1462 } 1458 }
1463 } 1459 }
1464 else 1460 else
1465 { 1461 {
1466 for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--) 1462 for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1467 { 1463 {
1468 reg_state[i].store_ruid = reload_combine_ruid; 1464 reg_state[i].store_ruid = reload_combine_ruid;
1469 if (GET_CODE (set) == SET) 1465 if (GET_CODE (set) == SET)
1470 reg_state[i].real_store_ruid = reload_combine_ruid; 1466 reg_state[i].real_store_ruid = reload_combine_ruid;
1471 reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; 1467 reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
1476 /* XP points to a piece of rtl that has to be checked for any uses of 1472 /* XP points to a piece of rtl that has to be checked for any uses of
1477 registers. 1473 registers.
1478 *XP is the pattern of INSN, or a part of it. 1474 *XP is the pattern of INSN, or a part of it.
1479 Called from reload_combine, and recursively by itself. */ 1475 Called from reload_combine, and recursively by itself. */
1480 static void 1476 static void
1481 reload_combine_note_use (rtx *xp, rtx insn, int ruid, rtx containing_mem) 1477 reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1482 { 1478 {
1483 rtx x = *xp; 1479 rtx x = *xp;
1484 enum rtx_code code = x->code; 1480 enum rtx_code code = x->code;
1485 const char *fmt; 1481 const char *fmt;
1486 int i, j; 1482 int i, j;
1498 1494
1499 case USE: 1495 case USE:
1500 /* If this is the USE of a return value, we can't change it. */ 1496 /* If this is the USE of a return value, we can't change it. */
1501 if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0))) 1497 if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
1502 { 1498 {
1503 /* Mark the return register as used in an unknown fashion. */ 1499 /* Mark the return register as used in an unknown fashion. */
1504 rtx reg = XEXP (x, 0); 1500 rtx reg = XEXP (x, 0);
1505 int regno = REGNO (reg); 1501 unsigned int end_regno = END_REGNO (reg);
1506 int nregs = hard_regno_nregs[regno][GET_MODE (reg)]; 1502 for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1507 1503 reg_state[regno].use_index = -1;
1508 while (--nregs >= 0)
1509 reg_state[regno + nregs].use_index = -1;
1510 return; 1504 return;
1511 } 1505 }
1512 break; 1506 break;
1513 1507
1514 case CLOBBER: 1508 case CLOBBER:
1535 int nregs; 1529 int nregs;
1536 1530
1537 /* No spurious USEs of pseudo registers may remain. */ 1531 /* No spurious USEs of pseudo registers may remain. */
1538 gcc_assert (regno < FIRST_PSEUDO_REGISTER); 1532 gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1539 1533
1540 nregs = hard_regno_nregs[regno][GET_MODE (x)]; 1534 nregs = REG_NREGS (x);
1541 1535
1542 /* We can't substitute into multi-hard-reg uses. */ 1536 /* We can't substitute into multi-hard-reg uses. */
1543 if (nregs > 1) 1537 if (nregs > 1)
1544 { 1538 {
1545 while (--nregs >= 0) 1539 while (--nregs >= 0)
1614 information about register contents we have would be costly, so we 1608 information about register contents we have would be costly, so we
1615 use move2add_last_label_luid to note where the label is and then 1609 use move2add_last_label_luid to note where the label is and then
1616 later disable any optimization that would cross it. 1610 later disable any optimization that would cross it.
1617 reg_offset[n] / reg_base_reg[n] / reg_symbol_ref[n] / reg_mode[n] 1611 reg_offset[n] / reg_base_reg[n] / reg_symbol_ref[n] / reg_mode[n]
1618 are only valid if reg_set_luid[n] is greater than 1612 are only valid if reg_set_luid[n] is greater than
1619 move2add_last_label_luid. */ 1613 move2add_last_label_luid.
1614 For a set that established a new (potential) base register with
1615 non-constant value, we use move2add_luid from the place where the
1616 setting insn is encountered; registers based off that base then
1617 get the same reg_set_luid. Constants all get
1618 move2add_last_label_luid + 1 as their reg_set_luid. */
1620 static int reg_set_luid[FIRST_PSEUDO_REGISTER]; 1619 static int reg_set_luid[FIRST_PSEUDO_REGISTER];
1621 1620
1622 /* If reg_base_reg[n] is negative, register n has been set to 1621 /* If reg_base_reg[n] is negative, register n has been set to
1623 reg_offset[n] or reg_symbol_ref[n] + reg_offset[n] in mode reg_mode[n]. 1622 reg_offset[n] or reg_symbol_ref[n] + reg_offset[n] in mode reg_mode[n].
1624 If reg_base_reg[n] is non-negative, register n has been set to the 1623 If reg_base_reg[n] is non-negative, register n has been set to the
1625 sum of reg_offset[n] and the value of register reg_base_reg[n] 1624 sum of reg_offset[n] and the value of register reg_base_reg[n]
1626 before reg_set_luid[n], calculated in mode reg_mode[n] . */ 1625 before reg_set_luid[n], calculated in mode reg_mode[n] .
1626 For multi-hard-register registers, all but the first one are
1627 recorded as BLKmode in reg_mode. Setting reg_mode to VOIDmode
1628 marks it as invalid. */
1627 static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER]; 1629 static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
1628 static int reg_base_reg[FIRST_PSEUDO_REGISTER]; 1630 static int reg_base_reg[FIRST_PSEUDO_REGISTER];
1629 static rtx reg_symbol_ref[FIRST_PSEUDO_REGISTER]; 1631 static rtx reg_symbol_ref[FIRST_PSEUDO_REGISTER];
1630 static enum machine_mode reg_mode[FIRST_PSEUDO_REGISTER]; 1632 static machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
1631 1633
1632 /* move2add_luid is linearly increased while scanning the instructions 1634 /* move2add_luid is linearly increased while scanning the instructions
1633 from first to last. It is used to set reg_set_luid in 1635 from first to last. It is used to set reg_set_luid in
1634 reload_cse_move2add and move2add_note_store. */ 1636 reload_cse_move2add and move2add_note_store. */
1635 static int move2add_luid; 1637 static int move2add_luid;
1641 /* ??? We don't know how zero / sign extension is handled, hence we 1643 /* ??? We don't know how zero / sign extension is handled, hence we
1642 can't go from a narrower to a wider mode. */ 1644 can't go from a narrower to a wider mode. */
1643 #define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \ 1645 #define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
1644 (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \ 1646 (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
1645 || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \ 1647 || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
1646 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \ 1648 && TRULY_NOOP_TRUNCATION_MODES_P (OUTMODE, INMODE)))
1647 GET_MODE_BITSIZE (INMODE)))) 1649
1648 1650 /* Record that REG is being set to a value with the mode of REG. */
1649 /* This function is called with INSN that sets REG to (SYM + OFF), 1651
1650 while REG is known to already have value (SYM + offset). 1652 static void
1653 move2add_record_mode (rtx reg)
1654 {
1655 int regno, nregs;
1656 machine_mode mode = GET_MODE (reg);
1657
1658 if (GET_CODE (reg) == SUBREG)
1659 {
1660 regno = subreg_regno (reg);
1661 nregs = subreg_nregs (reg);
1662 }
1663 else if (REG_P (reg))
1664 {
1665 regno = REGNO (reg);
1666 nregs = REG_NREGS (reg);
1667 }
1668 else
1669 gcc_unreachable ();
1670 for (int i = nregs - 1; i > 0; i--)
1671 reg_mode[regno + i] = BLKmode;
1672 reg_mode[regno] = mode;
1673 }
1674
1675 /* Record that REG is being set to the sum of SYM and OFF. */
1676
1677 static void
1678 move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1679 {
1680 int regno = REGNO (reg);
1681
1682 move2add_record_mode (reg);
1683 reg_set_luid[regno] = move2add_luid;
1684 reg_base_reg[regno] = -1;
1685 reg_symbol_ref[regno] = sym;
1686 reg_offset[regno] = INTVAL (off);
1687 }
1688
1689 /* Check if REGNO contains a valid value in MODE. */
1690
1691 static bool
1692 move2add_valid_value_p (int regno, scalar_int_mode mode)
1693 {
1694 if (reg_set_luid[regno] <= move2add_last_label_luid)
1695 return false;
1696
1697 if (mode != reg_mode[regno])
1698 {
1699 scalar_int_mode old_mode;
1700 if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1701 || !MODES_OK_FOR_MOVE2ADD (mode, old_mode))
1702 return false;
1703 /* The value loaded into regno in reg_mode[regno] is also valid in
1704 mode after truncation only if (REG:mode regno) is the lowpart of
1705 (REG:reg_mode[regno] regno). Now, for big endian, the starting
1706 regno of the lowpart might be different. */
1707 int s_off = subreg_lowpart_offset (mode, old_mode);
1708 s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1709 if (s_off != 0)
1710 /* We could in principle adjust regno, check reg_mode[regno] to be
1711 BLKmode, and return s_off to the caller (vs. -1 for failure),
1712 but we currently have no callers that could make use of this
1713 information. */
1714 return false;
1715 }
1716
1717 for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1718 if (reg_mode[i] != BLKmode)
1719 return false;
1720 return true;
1721 }
1722
1723 /* This function is called with INSN that sets REG (of mode MODE)
1724 to (SYM + OFF), while REG is known to already have value (SYM + offset).
1651 This function tries to change INSN into an add instruction 1725 This function tries to change INSN into an add instruction
1652 (set (REG) (plus (REG) (OFF - offset))) using the known value. 1726 (set (REG) (plus (REG) (OFF - offset))) using the known value.
1653 It also updates the information about REG's known value. 1727 It also updates the information about REG's known value.
1654 Return true if we made a change. */ 1728 Return true if we made a change. */
1655 1729
1656 static bool 1730 static bool
1657 move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx insn) 1731 move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1732 rtx_insn *insn)
1658 { 1733 {
1659 rtx pat = PATTERN (insn); 1734 rtx pat = PATTERN (insn);
1660 rtx src = SET_SRC (pat); 1735 rtx src = SET_SRC (pat);
1661 int regno = REGNO (reg); 1736 int regno = REGNO (reg);
1662 rtx new_src = gen_int_mode (INTVAL (off) - reg_offset[regno], 1737 rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1663 GET_MODE (reg));
1664 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); 1738 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1665 bool changed = false; 1739 bool changed = false;
1666 1740
1667 /* (set (reg) (plus (reg) (const_int 0))) is not canonical; 1741 /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1668 use (set (reg) (reg)) instead. 1742 use (set (reg) (reg)) instead.
1680 changed = validate_change (insn, &SET_SRC (pat), reg, 0); 1754 changed = validate_change (insn, &SET_SRC (pat), reg, 0);
1681 } 1755 }
1682 else 1756 else
1683 { 1757 {
1684 struct full_rtx_costs oldcst, newcst; 1758 struct full_rtx_costs oldcst, newcst;
1685 rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src); 1759 rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1686 1760
1687 get_full_rtx_cost (pat, SET, &oldcst); 1761 get_full_set_rtx_cost (pat, &oldcst);
1688 SET_SRC (pat) = tem; 1762 SET_SRC (pat) = tem;
1689 get_full_rtx_cost (pat, SET, &newcst); 1763 get_full_set_rtx_cost (pat, &newcst);
1690 SET_SRC (pat) = src; 1764 SET_SRC (pat) = src;
1691 1765
1692 if (costs_lt_p (&newcst, &oldcst, speed) 1766 if (costs_lt_p (&newcst, &oldcst, speed)
1693 && have_add2_insn (reg, new_src)) 1767 && have_add2_insn (reg, new_src))
1694 changed = validate_change (insn, &SET_SRC (pat), tem, 0); 1768 changed = validate_change (insn, &SET_SRC (pat), tem, 0);
1695 else if (sym == NULL_RTX && GET_MODE (reg) != BImode) 1769 else if (sym == NULL_RTX && mode != BImode)
1696 { 1770 {
1697 enum machine_mode narrow_mode; 1771 scalar_int_mode narrow_mode;
1698 for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT); 1772 FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1699 narrow_mode != VOIDmode
1700 && narrow_mode != GET_MODE (reg);
1701 narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
1702 { 1773 {
1703 if (have_insn_for (STRICT_LOW_PART, narrow_mode) 1774 if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1704 && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode)) 1775 && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1705 == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode)))) 1776 == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1706 { 1777 {
1707 rtx narrow_reg = gen_rtx_REG (narrow_mode, 1778 rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1708 REGNO (reg));
1709 rtx narrow_src = gen_int_mode (INTVAL (off), 1779 rtx narrow_src = gen_int_mode (INTVAL (off),
1710 narrow_mode); 1780 narrow_mode);
1711 rtx new_set 1781 rtx new_set
1712 = gen_rtx_SET (VOIDmode, 1782 = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1713 gen_rtx_STRICT_LOW_PART (VOIDmode,
1714 narrow_reg), 1783 narrow_reg),
1715 narrow_src); 1784 narrow_src);
1716 changed = validate_change (insn, &PATTERN (insn), 1785 get_full_set_rtx_cost (new_set, &newcst);
1717 new_set, 0); 1786 if (costs_lt_p (&newcst, &oldcst, speed))
1718 if (changed) 1787 {
1719 break; 1788 changed = validate_change (insn, &PATTERN (insn),
1789 new_set, 0);
1790 if (changed)
1791 break;
1792 }
1720 } 1793 }
1721 } 1794 }
1722 } 1795 }
1723 } 1796 }
1724 reg_set_luid[regno] = move2add_luid; 1797 move2add_record_sym_value (reg, sym, off);
1725 reg_base_reg[regno] = -1;
1726 reg_mode[regno] = GET_MODE (reg);
1727 reg_symbol_ref[regno] = sym;
1728 reg_offset[regno] = INTVAL (off);
1729 return changed; 1798 return changed;
1730 } 1799 }
1731 1800
1732 1801
1733 /* This function is called with INSN that sets REG to (SYM + OFF), 1802 /* This function is called with INSN that sets REG (of mode MODE) to
1734 but REG doesn't have known value (SYM + offset). This function 1803 (SYM + OFF), but REG doesn't have known value (SYM + offset). This
1735 tries to find another register which is known to already have 1804 function tries to find another register which is known to already have
1736 value (SYM + offset) and change INSN into an add instruction 1805 value (SYM + offset) and change INSN into an add instruction
1737 (set (REG) (plus (the found register) (OFF - offset))) if such 1806 (set (REG) (plus (the found register) (OFF - offset))) if such
1738 a register is found. It also updates the information about 1807 a register is found. It also updates the information about
1739 REG's known value. 1808 REG's known value.
1740 Return true iff we made a change. */ 1809 Return true iff we made a change. */
1741 1810
1742 static bool 1811 static bool
1743 move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx insn) 1812 move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1813 rtx_insn *insn)
1744 { 1814 {
1745 rtx pat = PATTERN (insn); 1815 rtx pat = PATTERN (insn);
1746 rtx src = SET_SRC (pat); 1816 rtx src = SET_SRC (pat);
1747 int regno = REGNO (reg); 1817 int regno = REGNO (reg);
1748 int min_regno = 0; 1818 int min_regno = 0;
1751 bool changed = false; 1821 bool changed = false;
1752 struct full_rtx_costs oldcst, newcst, mincst; 1822 struct full_rtx_costs oldcst, newcst, mincst;
1753 rtx plus_expr; 1823 rtx plus_expr;
1754 1824
1755 init_costs_to_max (&mincst); 1825 init_costs_to_max (&mincst);
1756 get_full_rtx_cost (pat, SET, &oldcst); 1826 get_full_set_rtx_cost (pat, &oldcst);
1757 1827
1758 plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx); 1828 plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1759 SET_SRC (pat) = plus_expr; 1829 SET_SRC (pat) = plus_expr;
1760 1830
1761 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 1831 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1762 if (reg_set_luid[i] > move2add_last_label_luid 1832 if (move2add_valid_value_p (i, mode)
1763 && reg_mode[i] == GET_MODE (reg)
1764 && reg_base_reg[i] < 0 1833 && reg_base_reg[i] < 0
1765 && reg_symbol_ref[i] != NULL_RTX 1834 && reg_symbol_ref[i] != NULL_RTX
1766 && rtx_equal_p (sym, reg_symbol_ref[i])) 1835 && rtx_equal_p (sym, reg_symbol_ref[i]))
1767 { 1836 {
1768 rtx new_src = gen_int_mode (INTVAL (off) - reg_offset[i], 1837 rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1769 GET_MODE (reg)); 1838 GET_MODE (reg));
1770 /* (set (reg) (plus (reg) (const_int 0))) is not canonical; 1839 /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1771 use (set (reg) (reg)) instead. 1840 use (set (reg) (reg)) instead.
1772 We don't delete this insn, nor do we convert it into a 1841 We don't delete this insn, nor do we convert it into a
1773 note, to avoid losing register notes or the return 1842 note, to avoid losing register notes or the return
1780 break; 1849 break;
1781 } 1850 }
1782 else 1851 else
1783 { 1852 {
1784 XEXP (plus_expr, 1) = new_src; 1853 XEXP (plus_expr, 1) = new_src;
1785 get_full_rtx_cost (pat, SET, &newcst); 1854 get_full_set_rtx_cost (pat, &newcst);
1786 1855
1787 if (costs_lt_p (&newcst, &mincst, speed)) 1856 if (costs_lt_p (&newcst, &mincst, speed))
1788 { 1857 {
1789 mincst = newcst; 1858 mincst = newcst;
1790 min_regno = i; 1859 min_regno = i;
1798 rtx tem; 1867 rtx tem;
1799 1868
1800 tem = gen_rtx_REG (GET_MODE (reg), min_regno); 1869 tem = gen_rtx_REG (GET_MODE (reg), min_regno);
1801 if (i != min_regno) 1870 if (i != min_regno)
1802 { 1871 {
1803 rtx new_src = gen_int_mode (INTVAL (off) - reg_offset[min_regno], 1872 rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[min_regno],
1804 GET_MODE (reg)); 1873 GET_MODE (reg));
1805 tem = gen_rtx_PLUS (GET_MODE (reg), tem, new_src); 1874 tem = gen_rtx_PLUS (GET_MODE (reg), tem, new_src);
1806 } 1875 }
1807 if (validate_change (insn, &SET_SRC (pat), tem, 0)) 1876 if (validate_change (insn, &SET_SRC (pat), tem, 0))
1808 changed = true; 1877 changed = true;
1809 } 1878 }
1810 reg_set_luid[regno] = move2add_luid; 1879 reg_set_luid[regno] = move2add_luid;
1811 reg_base_reg[regno] = -1; 1880 move2add_record_sym_value (reg, sym, off);
1812 reg_mode[regno] = GET_MODE (reg);
1813 reg_symbol_ref[regno] = sym;
1814 reg_offset[regno] = INTVAL (off);
1815 return changed; 1881 return changed;
1816 } 1882 }
1817 1883
1818 /* Convert move insns with constant inputs to additions if they are cheaper. 1884 /* Convert move insns with constant inputs to additions if they are cheaper.
1819 Return true if any changes were made. */ 1885 Return true if any changes were made. */
1820 static bool 1886 static bool
1821 reload_cse_move2add (rtx first) 1887 reload_cse_move2add (rtx_insn *first)
1822 { 1888 {
1823 int i; 1889 int i;
1824 rtx insn; 1890 rtx_insn *insn;
1825 bool changed = false; 1891 bool changed = false;
1826 1892
1827 for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) 1893 for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
1828 { 1894 {
1829 reg_set_luid[i] = 0; 1895 reg_set_luid[i] = 0;
1851 if (! INSN_P (insn)) 1917 if (! INSN_P (insn))
1852 continue; 1918 continue;
1853 pat = PATTERN (insn); 1919 pat = PATTERN (insn);
1854 /* For simplicity, we only perform this optimization on 1920 /* For simplicity, we only perform this optimization on
1855 straightforward SETs. */ 1921 straightforward SETs. */
1922 scalar_int_mode mode;
1856 if (GET_CODE (pat) == SET 1923 if (GET_CODE (pat) == SET
1857 && REG_P (SET_DEST (pat))) 1924 && REG_P (SET_DEST (pat))
1925 && is_a <scalar_int_mode> (GET_MODE (SET_DEST (pat)), &mode))
1858 { 1926 {
1859 rtx reg = SET_DEST (pat); 1927 rtx reg = SET_DEST (pat);
1860 int regno = REGNO (reg); 1928 int regno = REGNO (reg);
1861 rtx src = SET_SRC (pat); 1929 rtx src = SET_SRC (pat);
1862 1930
1863 /* Check if we have valid information on the contents of this 1931 /* Check if we have valid information on the contents of this
1864 register in the mode of REG. */ 1932 register in the mode of REG. */
1865 if (reg_set_luid[regno] > move2add_last_label_luid 1933 if (move2add_valid_value_p (regno, mode)
1866 && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])
1867 && dbg_cnt (cse2_move2add)) 1934 && dbg_cnt (cse2_move2add))
1868 { 1935 {
1869 /* Try to transform (set (REGX) (CONST_INT A)) 1936 /* Try to transform (set (REGX) (CONST_INT A))
1870 ... 1937 ...
1871 (set (REGX) (CONST_INT B)) 1938 (set (REGX) (CONST_INT B))
1881 1948
1882 if (CONST_INT_P (src) 1949 if (CONST_INT_P (src)
1883 && reg_base_reg[regno] < 0 1950 && reg_base_reg[regno] < 0
1884 && reg_symbol_ref[regno] == NULL_RTX) 1951 && reg_symbol_ref[regno] == NULL_RTX)
1885 { 1952 {
1886 changed |= move2add_use_add2_insn (reg, NULL_RTX, src, insn); 1953 changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
1954 src, insn);
1887 continue; 1955 continue;
1888 } 1956 }
1889 1957
1890 /* Try to transform (set (REGX) (REGY)) 1958 /* Try to transform (set (REGX) (REGY))
1891 (set (REGX) (PLUS (REGX) (CONST_INT A))) 1959 (set (REGX) (PLUS (REGX) (CONST_INT A)))
1898 ... 1966 ...
1899 (set (REGX) (plus (REGX) (CONST_INT B-A))) */ 1967 (set (REGX) (plus (REGX) (CONST_INT B-A))) */
1900 else if (REG_P (src) 1968 else if (REG_P (src)
1901 && reg_set_luid[regno] == reg_set_luid[REGNO (src)] 1969 && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
1902 && reg_base_reg[regno] == reg_base_reg[REGNO (src)] 1970 && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
1903 && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), 1971 && move2add_valid_value_p (REGNO (src), mode))
1904 reg_mode[REGNO (src)]))
1905 { 1972 {
1906 rtx next = next_nonnote_nondebug_insn (insn); 1973 rtx_insn *next = next_nonnote_nondebug_insn (insn);
1907 rtx set = NULL_RTX; 1974 rtx set = NULL_RTX;
1908 if (next) 1975 if (next)
1909 set = single_set (next); 1976 set = single_set (next);
1910 if (set 1977 if (set
1911 && SET_DEST (set) == reg 1978 && SET_DEST (set) == reg
1912 && GET_CODE (SET_SRC (set)) == PLUS 1979 && GET_CODE (SET_SRC (set)) == PLUS
1913 && XEXP (SET_SRC (set), 0) == reg 1980 && XEXP (SET_SRC (set), 0) == reg
1914 && CONST_INT_P (XEXP (SET_SRC (set), 1))) 1981 && CONST_INT_P (XEXP (SET_SRC (set), 1)))
1915 { 1982 {
1916 rtx src3 = XEXP (SET_SRC (set), 1); 1983 rtx src3 = XEXP (SET_SRC (set), 1);
1917 HOST_WIDE_INT added_offset = INTVAL (src3); 1984 unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
1918 HOST_WIDE_INT base_offset = reg_offset[REGNO (src)]; 1985 HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
1919 HOST_WIDE_INT regno_offset = reg_offset[regno]; 1986 HOST_WIDE_INT regno_offset = reg_offset[regno];
1920 rtx new_src = 1987 rtx new_src =
1921 gen_int_mode (added_offset 1988 gen_int_mode (added_offset
1922 + base_offset 1989 + base_offset
1923 - regno_offset, 1990 - regno_offset,
1924 GET_MODE (reg)); 1991 mode);
1925 bool success = false; 1992 bool success = false;
1926 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); 1993 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1927 1994
1928 if (new_src == const0_rtx) 1995 if (new_src == const0_rtx)
1929 /* See above why we create (set (reg) (reg)) here. */ 1996 /* See above why we create (set (reg) (reg)) here. */
1931 = validate_change (next, &SET_SRC (set), reg, 0); 1998 = validate_change (next, &SET_SRC (set), reg, 0);
1932 else 1999 else
1933 { 2000 {
1934 rtx old_src = SET_SRC (set); 2001 rtx old_src = SET_SRC (set);
1935 struct full_rtx_costs oldcst, newcst; 2002 struct full_rtx_costs oldcst, newcst;
1936 rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src); 2003 rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1937 2004
1938 get_full_rtx_cost (set, SET, &oldcst); 2005 get_full_set_rtx_cost (set, &oldcst);
1939 SET_SRC (set) = tem; 2006 SET_SRC (set) = tem;
1940 get_full_rtx_cost (tem, SET, &newcst); 2007 get_full_set_src_cost (tem, mode, &newcst);
1941 SET_SRC (set) = old_src; 2008 SET_SRC (set) = old_src;
1942 costs_add_n_insns (&oldcst, 1); 2009 costs_add_n_insns (&oldcst, 1);
1943 2010
1944 if (costs_lt_p (&newcst, &oldcst, speed) 2011 if (costs_lt_p (&newcst, &oldcst, speed)
1945 && have_add2_insn (reg, new_src)) 2012 && have_add2_insn (reg, new_src))
1946 { 2013 {
1947 rtx newpat = gen_rtx_SET (VOIDmode, reg, tem); 2014 rtx newpat = gen_rtx_SET (reg, tem);
1948 success 2015 success
1949 = validate_change (next, &PATTERN (next), 2016 = validate_change (next, &PATTERN (next),
1950 newpat, 0); 2017 newpat, 0);
1951 } 2018 }
1952 } 2019 }
1953 if (success) 2020 if (success)
1954 delete_insn (insn); 2021 delete_insn (insn);
1955 changed |= success; 2022 changed |= success;
1956 insn = next; 2023 insn = next;
1957 reg_mode[regno] = GET_MODE (reg); 2024 move2add_record_mode (reg);
1958 reg_offset[regno] = 2025 reg_offset[regno]
1959 trunc_int_for_mode (added_offset + base_offset, 2026 = trunc_int_for_mode (added_offset + base_offset,
1960 GET_MODE (reg)); 2027 mode);
1961 continue; 2028 continue;
1962 } 2029 }
1963 } 2030 }
1964 } 2031 }
1965 2032
1991 off = XEXP (XEXP (src, 0), 1); 2058 off = XEXP (XEXP (src, 0), 1);
1992 } 2059 }
1993 2060
1994 /* If the reg already contains the value which is sum of 2061 /* If the reg already contains the value which is sum of
1995 sym and some constant value, we can use an add2 insn. */ 2062 sym and some constant value, we can use an add2 insn. */
1996 if (reg_set_luid[regno] > move2add_last_label_luid 2063 if (move2add_valid_value_p (regno, mode)
1997 && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])
1998 && reg_base_reg[regno] < 0 2064 && reg_base_reg[regno] < 0
1999 && reg_symbol_ref[regno] != NULL_RTX 2065 && reg_symbol_ref[regno] != NULL_RTX
2000 && rtx_equal_p (sym, reg_symbol_ref[regno])) 2066 && rtx_equal_p (sym, reg_symbol_ref[regno]))
2001 changed |= move2add_use_add2_insn (reg, sym, off, insn); 2067 changed |= move2add_use_add2_insn (mode, reg, sym, off, insn);
2002 2068
2003 /* Otherwise, we have to find a register whose value is sum 2069 /* Otherwise, we have to find a register whose value is sum
2004 of sym and some constant value. */ 2070 of sym and some constant value. */
2005 else 2071 else
2006 changed |= move2add_use_add3_insn (reg, sym, off, insn); 2072 changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2007 2073
2008 continue; 2074 continue;
2009 } 2075 }
2010 } 2076 }
2011 2077
2015 && REG_P (XEXP (note, 0))) 2081 && REG_P (XEXP (note, 0)))
2016 { 2082 {
2017 /* Reset the information about this register. */ 2083 /* Reset the information about this register. */
2018 int regno = REGNO (XEXP (note, 0)); 2084 int regno = REGNO (XEXP (note, 0));
2019 if (regno < FIRST_PSEUDO_REGISTER) 2085 if (regno < FIRST_PSEUDO_REGISTER)
2020 reg_set_luid[regno] = 0; 2086 {
2087 move2add_record_mode (XEXP (note, 0));
2088 reg_mode[regno] = VOIDmode;
2089 }
2021 } 2090 }
2022 } 2091 }
2023 note_stores (PATTERN (insn), move2add_note_store, insn); 2092 note_stores (PATTERN (insn), move2add_note_store, insn);
2024 2093
2025 /* If INSN is a conditional branch, we try to extract an 2094 /* If INSN is a conditional branch, we try to extract an
2035 /* The following two checks, which are also in 2104 /* The following two checks, which are also in
2036 move2add_note_store, are intended to reduce the 2105 move2add_note_store, are intended to reduce the
2037 number of calls to gen_rtx_SET to avoid memory 2106 number of calls to gen_rtx_SET to avoid memory
2038 allocation if possible. */ 2107 allocation if possible. */
2039 && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0))) 2108 && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2040 && hard_regno_nregs[REGNO (XEXP (cnd, 0))][GET_MODE (XEXP (cnd, 0))] == 1 2109 && REG_NREGS (XEXP (cnd, 0)) == 1
2041 && CONST_INT_P (XEXP (cnd, 1))) 2110 && CONST_INT_P (XEXP (cnd, 1)))
2042 { 2111 {
2043 rtx implicit_set = 2112 rtx implicit_set =
2044 gen_rtx_SET (VOIDmode, XEXP (cnd, 0), XEXP (cnd, 1)); 2113 gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2045 move2add_note_store (SET_DEST (implicit_set), implicit_set, insn); 2114 move2add_note_store (SET_DEST (implicit_set), implicit_set, insn);
2046 } 2115 }
2047 } 2116 }
2048 2117
2049 /* If this is a CALL_INSN, all call used registers are stored with 2118 /* If this is a CALL_INSN, all call used registers are stored with
2050 unknown values. */ 2119 unknown values. */
2051 if (CALL_P (insn)) 2120 if (CALL_P (insn))
2052 { 2121 {
2122 rtx link;
2123
2053 for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) 2124 for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2054 { 2125 {
2055 if (call_used_regs[i]) 2126 if (call_used_regs[i])
2056 /* Reset the information about this register. */ 2127 /* Reset the information about this register. */
2057 reg_set_luid[i] = 0; 2128 reg_mode[i] = VOIDmode;
2129 }
2130
2131 for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
2132 link = XEXP (link, 1))
2133 {
2134 rtx setuse = XEXP (link, 0);
2135 rtx usage_rtx = XEXP (setuse, 0);
2136 if (GET_CODE (setuse) == CLOBBER
2137 && REG_P (usage_rtx))
2138 {
2139 unsigned int end_regno = END_REGNO (usage_rtx);
2140 for (unsigned int r = REGNO (usage_rtx); r < end_regno; ++r)
2141 /* Reset the information about this register. */
2142 reg_mode[r] = VOIDmode;
2143 }
2058 } 2144 }
2059 } 2145 }
2060 } 2146 }
2061 return changed; 2147 return changed;
2062 } 2148 }
2067 Called from reload_cse_move2add via note_stores. */ 2153 Called from reload_cse_move2add via note_stores. */
2068 2154
2069 static void 2155 static void
2070 move2add_note_store (rtx dst, const_rtx set, void *data) 2156 move2add_note_store (rtx dst, const_rtx set, void *data)
2071 { 2157 {
2072 rtx insn = (rtx) data; 2158 rtx_insn *insn = (rtx_insn *) data;
2073 unsigned int regno = 0; 2159 unsigned int regno = 0;
2074 unsigned int nregs = 0; 2160 scalar_int_mode mode;
2075 unsigned int i;
2076 enum machine_mode mode = GET_MODE (dst);
2077
2078 if (GET_CODE (dst) == SUBREG)
2079 {
2080 regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
2081 GET_MODE (SUBREG_REG (dst)),
2082 SUBREG_BYTE (dst),
2083 GET_MODE (dst));
2084 nregs = subreg_nregs (dst);
2085 dst = SUBREG_REG (dst);
2086 }
2087 2161
2088 /* Some targets do argument pushes without adding REG_INC notes. */ 2162 /* Some targets do argument pushes without adding REG_INC notes. */
2089 2163
2090 if (MEM_P (dst)) 2164 if (MEM_P (dst))
2091 { 2165 {
2092 dst = XEXP (dst, 0); 2166 dst = XEXP (dst, 0);
2093 if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC 2167 if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
2094 || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC) 2168 || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC)
2095 reg_set_luid[REGNO (XEXP (dst, 0))] = 0; 2169 reg_mode[REGNO (XEXP (dst, 0))] = VOIDmode;
2096 return; 2170 return;
2097 } 2171 }
2098 if (!REG_P (dst)) 2172
2173 if (GET_CODE (dst) == SUBREG)
2174 regno = subreg_regno (dst);
2175 else if (REG_P (dst))
2176 regno = REGNO (dst);
2177 else
2099 return; 2178 return;
2100 2179
2101 regno += REGNO (dst); 2180 if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2102 if (!nregs) 2181 goto invalidate;
2103 nregs = hard_regno_nregs[regno][mode]; 2182
2104 2183 if (GET_CODE (set) == SET)
2105 if (SCALAR_INT_MODE_P (GET_MODE (dst))
2106 && nregs == 1 && GET_CODE (set) == SET)
2107 { 2184 {
2108 rtx note, sym = NULL_RTX; 2185 rtx note, sym = NULL_RTX;
2109 HOST_WIDE_INT off; 2186 rtx off;
2110 2187
2111 note = find_reg_equal_equiv_note (insn); 2188 note = find_reg_equal_equiv_note (insn);
2112 if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF) 2189 if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2113 { 2190 {
2114 sym = XEXP (note, 0); 2191 sym = XEXP (note, 0);
2115 off = 0; 2192 off = const0_rtx;
2116 } 2193 }
2117 else if (note && GET_CODE (XEXP (note, 0)) == CONST 2194 else if (note && GET_CODE (XEXP (note, 0)) == CONST
2118 && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS 2195 && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2119 && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF 2196 && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2120 && CONST_INT_P (XEXP (XEXP (XEXP (note, 0), 0), 1))) 2197 && CONST_INT_P (XEXP (XEXP (XEXP (note, 0), 0), 1)))
2121 { 2198 {
2122 sym = XEXP (XEXP (XEXP (note, 0), 0), 0); 2199 sym = XEXP (XEXP (XEXP (note, 0), 0), 0);
2123 off = INTVAL (XEXP (XEXP (XEXP (note, 0), 0), 1)); 2200 off = XEXP (XEXP (XEXP (note, 0), 0), 1);
2124 } 2201 }
2125 2202
2126 if (sym != NULL_RTX) 2203 if (sym != NULL_RTX)
2127 { 2204 {
2128 reg_base_reg[regno] = -1; 2205 move2add_record_sym_value (dst, sym, off);
2129 reg_symbol_ref[regno] = sym;
2130 reg_offset[regno] = off;
2131 reg_mode[regno] = mode;
2132 reg_set_luid[regno] = move2add_luid;
2133 return; 2206 return;
2134 } 2207 }
2135 } 2208 }
2136 2209
2137 if (SCALAR_INT_MODE_P (GET_MODE (dst)) 2210 if (GET_CODE (set) == SET
2138 && nregs == 1 && GET_CODE (set) == SET
2139 && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT 2211 && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2140 && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART) 2212 && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2141 { 2213 {
2142 rtx src = SET_SRC (set); 2214 rtx src = SET_SRC (set);
2143 rtx base_reg; 2215 rtx base_reg;
2144 HOST_WIDE_INT offset; 2216 unsigned HOST_WIDE_INT offset;
2145 int base_regno; 2217 int base_regno;
2146 /* This may be different from mode, if SET_DEST (set) is a
2147 SUBREG. */
2148 enum machine_mode dst_mode = GET_MODE (dst);
2149 2218
2150 switch (GET_CODE (src)) 2219 switch (GET_CODE (src))
2151 { 2220 {
2152 case PLUS: 2221 case PLUS:
2153 if (REG_P (XEXP (src, 0))) 2222 if (REG_P (XEXP (src, 0)))
2154 { 2223 {
2155 base_reg = XEXP (src, 0); 2224 base_reg = XEXP (src, 0);
2156 2225
2157 if (CONST_INT_P (XEXP (src, 1))) 2226 if (CONST_INT_P (XEXP (src, 1)))
2158 offset = INTVAL (XEXP (src, 1)); 2227 offset = UINTVAL (XEXP (src, 1));
2159 else if (REG_P (XEXP (src, 1)) 2228 else if (REG_P (XEXP (src, 1))
2160 && (reg_set_luid[REGNO (XEXP (src, 1))] 2229 && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2161 > move2add_last_label_luid)
2162 && (MODES_OK_FOR_MOVE2ADD
2163 (dst_mode, reg_mode[REGNO (XEXP (src, 1))])))
2164 { 2230 {
2165 if (reg_base_reg[REGNO (XEXP (src, 1))] < 0 2231 if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2166 && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX) 2232 && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2167 offset = reg_offset[REGNO (XEXP (src, 1))]; 2233 offset = reg_offset[REGNO (XEXP (src, 1))];
2168 /* Maybe the first register is known to be a 2234 /* Maybe the first register is known to be a
2169 constant. */ 2235 constant. */
2170 else if (reg_set_luid[REGNO (base_reg)] 2236 else if (move2add_valid_value_p (REGNO (base_reg), mode)
2171 > move2add_last_label_luid
2172 && (MODES_OK_FOR_MOVE2ADD
2173 (dst_mode, reg_mode[REGNO (base_reg)]))
2174 && reg_base_reg[REGNO (base_reg)] < 0 2237 && reg_base_reg[REGNO (base_reg)] < 0
2175 && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX) 2238 && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2176 { 2239 {
2177 offset = reg_offset[REGNO (base_reg)]; 2240 offset = reg_offset[REGNO (base_reg)];
2178 base_reg = XEXP (src, 1); 2241 base_reg = XEXP (src, 1);
2198 reg_base_reg[regno] = -1; 2261 reg_base_reg[regno] = -1;
2199 reg_symbol_ref[regno] = NULL_RTX; 2262 reg_symbol_ref[regno] = NULL_RTX;
2200 reg_offset[regno] = INTVAL (SET_SRC (set)); 2263 reg_offset[regno] = INTVAL (SET_SRC (set));
2201 /* We assign the same luid to all registers set to constants. */ 2264 /* We assign the same luid to all registers set to constants. */
2202 reg_set_luid[regno] = move2add_last_label_luid + 1; 2265 reg_set_luid[regno] = move2add_last_label_luid + 1;
2203 reg_mode[regno] = mode; 2266 move2add_record_mode (dst);
2204 return; 2267 return;
2205 2268
2206 default: 2269 default:
2207 invalidate: 2270 goto invalidate;
2208 /* Invalidate the contents of the register. */
2209 reg_set_luid[regno] = 0;
2210 return;
2211 } 2271 }
2212 2272
2213 base_regno = REGNO (base_reg); 2273 base_regno = REGNO (base_reg);
2214 /* If information about the base register is not valid, set it 2274 /* If information about the base register is not valid, set it
2215 up as a new base register, pretending its value is known 2275 up as a new base register, pretending its value is known
2216 starting from the current insn. */ 2276 starting from the current insn. */
2217 if (reg_set_luid[base_regno] <= move2add_last_label_luid) 2277 if (!move2add_valid_value_p (base_regno, mode))
2218 { 2278 {
2219 reg_base_reg[base_regno] = base_regno; 2279 reg_base_reg[base_regno] = base_regno;
2220 reg_symbol_ref[base_regno] = NULL_RTX; 2280 reg_symbol_ref[base_regno] = NULL_RTX;
2221 reg_offset[base_regno] = 0; 2281 reg_offset[base_regno] = 0;
2222 reg_set_luid[base_regno] = move2add_luid; 2282 reg_set_luid[base_regno] = move2add_luid;
2223 reg_mode[base_regno] = mode; 2283 gcc_assert (GET_MODE (base_reg) == mode);
2224 } 2284 move2add_record_mode (base_reg);
2225 else if (! MODES_OK_FOR_MOVE2ADD (dst_mode, 2285 }
2226 reg_mode[base_regno]))
2227 goto invalidate;
2228
2229 reg_mode[regno] = mode;
2230 2286
2231 /* Copy base information from our base register. */ 2287 /* Copy base information from our base register. */
2232 reg_set_luid[regno] = reg_set_luid[base_regno]; 2288 reg_set_luid[regno] = reg_set_luid[base_regno];
2233 reg_base_reg[regno] = reg_base_reg[base_regno]; 2289 reg_base_reg[regno] = reg_base_reg[base_regno];
2234 reg_symbol_ref[regno] = reg_symbol_ref[base_regno]; 2290 reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2235 2291
2236 /* Compute the sum of the offsets or constants. */ 2292 /* Compute the sum of the offsets or constants. */
2237 reg_offset[regno] = trunc_int_for_mode (offset 2293 reg_offset[regno]
2238 + reg_offset[base_regno], 2294 = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2239 dst_mode); 2295
2296 move2add_record_mode (dst);
2240 } 2297 }
2241 else 2298 else
2242 { 2299 {
2243 unsigned int endregno = regno + nregs; 2300 invalidate:
2244 2301 /* Invalidate the contents of the register. */
2245 for (i = regno; i < endregno; i++) 2302 move2add_record_mode (dst);
2246 /* Reset the information about this register. */ 2303 reg_mode[regno] = VOIDmode;
2247 reg_set_luid[i] = 0;
2248 } 2304 }
2249 } 2305 }
2250 2306
2251 static bool 2307 namespace {
2252 gate_handle_postreload (void) 2308
2253 { 2309 const pass_data pass_data_postreload_cse =
2254 return (optimize > 0 && reload_completed); 2310 {
2255 } 2311 RTL_PASS, /* type */
2256 2312 "postreload", /* name */
2257 2313 OPTGROUP_NONE, /* optinfo_flags */
2258 static unsigned int 2314 TV_RELOAD_CSE_REGS, /* tv_id */
2259 rest_of_handle_postreload (void) 2315 0, /* properties_required */
2316 0, /* properties_provided */
2317 0, /* properties_destroyed */
2318 0, /* todo_flags_start */
2319 TODO_df_finish, /* todo_flags_finish */
2320 };
2321
2322 class pass_postreload_cse : public rtl_opt_pass
2323 {
2324 public:
2325 pass_postreload_cse (gcc::context *ctxt)
2326 : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2327 {}
2328
2329 /* opt_pass methods: */
2330 virtual bool gate (function *) { return (optimize > 0 && reload_completed); }
2331
2332 virtual unsigned int execute (function *);
2333
2334 }; // class pass_postreload_cse
2335
2336 unsigned int
2337 pass_postreload_cse::execute (function *fun)
2260 { 2338 {
2261 if (!dbg_cnt (postreload_cse)) 2339 if (!dbg_cnt (postreload_cse))
2262 return 0; 2340 return 0;
2263 2341
2264 /* Do a very simple CSE pass over just the hard registers. */ 2342 /* Do a very simple CSE pass over just the hard registers. */
2265 reload_cse_regs (get_insns ()); 2343 reload_cse_regs (get_insns ());
2266 /* Reload_cse_regs can eliminate potentially-trapping MEMs. 2344 /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2267 Remove any EH edges associated with them. */ 2345 Remove any EH edges associated with them. */
2268 if (cfun->can_throw_non_call_exceptions) 2346 if (fun->can_throw_non_call_exceptions
2269 purge_all_dead_edges (); 2347 && purge_all_dead_edges ())
2348 cleanup_cfg (0);
2270 2349
2271 return 0; 2350 return 0;
2272 } 2351 }
2273 2352
2274 struct rtl_opt_pass pass_postreload_cse = 2353 } // anon namespace
2275 { 2354
2276 { 2355 rtl_opt_pass *
2277 RTL_PASS, 2356 make_pass_postreload_cse (gcc::context *ctxt)
2278 "postreload", /* name */ 2357 {
2279 gate_handle_postreload, /* gate */ 2358 return new pass_postreload_cse (ctxt);
2280 rest_of_handle_postreload, /* execute */ 2359 }
2281 NULL, /* sub */
2282 NULL, /* next */
2283 0, /* static_pass_number */
2284 TV_RELOAD_CSE_REGS, /* tv_id */
2285 0, /* properties_required */
2286 0, /* properties_provided */
2287 0, /* properties_destroyed */
2288 0, /* todo_flags_start */
2289 TODO_df_finish | TODO_verify_rtl_sharing |
2290 TODO_dump_func /* todo_flags_finish */
2291 }
2292 };