Line data Source code
1 : /* Perform simple optimizations to clean up the result of reload.
2 : Copyright (C) 1987-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "backend.h"
24 : #include "target.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"
31 : #include "optabs.h"
32 : #include "regs.h"
33 : #include "emit-rtl.h"
34 : #include "recog.h"
35 :
36 : #include "cfghooks.h"
37 : #include "cfgrtl.h"
38 : #include "cfgbuild.h"
39 : #include "cfgcleanup.h"
40 : #include "reload.h"
41 : #include "cselib.h"
42 : #include "tree-pass.h"
43 : #include "dbgcnt.h"
44 : #include "function-abi.h"
45 : #include "rtl-iter.h"
46 :
47 : static bool reload_cse_simplify (rtx_insn *, rtx);
48 : static void reload_cse_regs_1 (void);
49 : static int reload_cse_simplify_set (rtx, rtx_insn *);
50 : static int reload_cse_simplify_operands (rtx_insn *, rtx);
51 :
52 : static void reload_combine (void);
53 : static void reload_combine_note_use (rtx *, rtx_insn *, int, rtx);
54 : static void reload_combine_note_store (rtx, const_rtx, void *);
55 :
56 : static bool reload_cse_move2add (rtx_insn *);
57 : static void move2add_note_store (rtx, const_rtx, void *);
58 :
59 : /* Call cse / combine like post-reload optimization phases.
60 : FIRST is the first instruction. */
61 :
62 : static void
63 1041770 : reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
64 : {
65 1041770 : bool moves_converted;
66 1041770 : reload_cse_regs_1 ();
67 1041770 : reload_combine ();
68 1041770 : moves_converted = reload_cse_move2add (first);
69 1041770 : if (flag_expensive_optimizations)
70 : {
71 961263 : if (moves_converted)
72 9281 : reload_combine ();
73 961263 : reload_cse_regs_1 ();
74 : }
75 1041770 : }
76 :
77 : /* Try to simplify INSN. Return true if the CFG may have changed. */
78 : static bool
79 206503026 : reload_cse_simplify (rtx_insn *insn, rtx testreg)
80 : {
81 206503026 : rtx body = PATTERN (insn);
82 206503026 : basic_block insn_bb = BLOCK_FOR_INSN (insn);
83 206503026 : unsigned insn_bb_succs = EDGE_COUNT (insn_bb->succs);
84 :
85 : /* If NO_FUNCTION_CSE has been set by the target, then we should not try
86 : to cse function calls. */
87 206503026 : if (NO_FUNCTION_CSE && CALL_P (insn))
88 : return false;
89 :
90 : /* Remember if this insn has been sp += const_int. */
91 197568535 : rtx sp_set = set_for_reg_notes (insn);
92 197568535 : rtx sp_addend = NULL_RTX;
93 197568535 : if (sp_set
94 67404292 : && SET_DEST (sp_set) == stack_pointer_rtx
95 3332620 : && GET_CODE (SET_SRC (sp_set)) == PLUS
96 3301968 : && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
97 3301865 : && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
98 197568535 : sp_addend = XEXP (SET_SRC (sp_set), 1);
99 :
100 197568535 : if (GET_CODE (body) == SET)
101 : {
102 87281356 : int count = 0;
103 :
104 : /* Simplify even if we may think it is a no-op.
105 : We may think a memory load of a value smaller than WORD_SIZE
106 : is redundant because we haven't taken into account possible
107 : implicit extension. reload_cse_simplify_set() will bring
108 : this out, so it's safer to simplify before we delete. */
109 87281356 : count += reload_cse_simplify_set (body, insn);
110 :
111 87281356 : if (!count && cselib_redundant_set_p (body))
112 : {
113 226264 : if (check_for_inc_dec (insn))
114 226264 : delete_insn_and_edges (insn);
115 : /* We're done with this insn. */
116 226264 : goto done;
117 : }
118 :
119 87055092 : if (count > 0)
120 146560 : apply_change_group ();
121 : else
122 86908532 : reload_cse_simplify_operands (insn, testreg);
123 : }
124 110287179 : else if (GET_CODE (body) == PARALLEL)
125 : {
126 13891103 : int i;
127 13891103 : int count = 0;
128 13891103 : rtx value = NULL_RTX;
129 :
130 : /* Registers mentioned in the clobber list for an asm cannot be reused
131 : within the body of the asm. Invalidate those registers now so that
132 : we don't try to substitute values for them. */
133 13891103 : if (asm_noperands (body) >= 0)
134 : {
135 617042 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
136 : {
137 470859 : rtx part = XVECEXP (body, 0, i);
138 470859 : if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
139 201012 : cselib_invalidate_rtx (XEXP (part, 0));
140 : }
141 : }
142 :
143 : /* If every action in a PARALLEL is a noop, we can delete
144 : the entire PARALLEL. */
145 27775099 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
146 : {
147 27771105 : rtx part = XVECEXP (body, 0, i);
148 27771105 : if (GET_CODE (part) == SET)
149 : {
150 13784872 : if (! cselib_redundant_set_p (part))
151 : break;
152 4061 : if (REG_P (SET_DEST (part))
153 4061 : && REG_FUNCTION_VALUE_P (SET_DEST (part)))
154 : {
155 0 : if (value)
156 : break;
157 : value = SET_DEST (part);
158 : }
159 : }
160 13986233 : else if (GET_CODE (part) != CLOBBER && GET_CODE (part) != USE)
161 : break;
162 : }
163 :
164 13891103 : if (i < 0)
165 : {
166 3994 : if (check_for_inc_dec (insn))
167 3994 : delete_insn_and_edges (insn);
168 : /* We're done with this insn. */
169 3994 : goto done;
170 : }
171 :
172 : /* It's not a no-op, but we can try to simplify it. */
173 42414547 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
174 28527438 : if (GET_CODE (XVECEXP (body, 0, i)) == SET)
175 14544983 : count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
176 :
177 13887109 : if (count > 0)
178 5437 : apply_change_group ();
179 : else
180 13881672 : reload_cse_simplify_operands (insn, testreg);
181 : }
182 :
183 : /* If sp += const_int insn is changed into sp = reg;, add REG_EQUAL
184 : note so that the stack_adjustments pass can undo it if beneficial. */
185 197338277 : if (sp_addend
186 3301865 : && SET_DEST (sp_set) == stack_pointer_rtx
187 3301865 : && REG_P (SET_SRC (sp_set)))
188 3045 : set_dst_reg_note (insn, REG_EQUAL,
189 3045 : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
190 : sp_addend), stack_pointer_rtx);
191 :
192 197335232 : done:
193 395134110 : return (EDGE_COUNT (insn_bb->succs) != insn_bb_succs);
194 : }
195 :
196 : /* Do a very simple CSE pass over the hard registers.
197 :
198 : This function detects no-op moves where we happened to assign two
199 : different pseudo-registers to the same hard register, and then
200 : copied one to the other. Reload will generate a useless
201 : instruction copying a register to itself.
202 :
203 : This function also detects cases where we load a value from memory
204 : into two different registers, and (if memory is more expensive than
205 : registers) changes it to simply copy the first register into the
206 : second register.
207 :
208 : Another optimization is performed that scans the operands of each
209 : instruction to see whether the value is already available in a
210 : hard register. It then replaces the operand with the hard register
211 : if possible, much like an optional reload would. */
212 :
213 : static void
214 2003033 : reload_cse_regs_1 (void)
215 : {
216 2003033 : bool cfg_changed = false;
217 2003033 : basic_block bb;
218 2003033 : rtx_insn *insn;
219 2003033 : rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
220 :
221 2003033 : cselib_init (CSELIB_RECORD_MEMORY);
222 2003033 : init_alias_analysis ();
223 :
224 23003381 : FOR_EACH_BB_FN (bb, cfun)
225 : {
226 : /* If BB has a small number of predecessors, see if each of the
227 : has the same implicit set. If so, record that implicit set so
228 : that we can add it to the cselib tables. */
229 21000348 : rtx_insn *implicit_set;
230 :
231 21000348 : implicit_set = NULL;
232 21000348 : if (EDGE_COUNT (bb->preds) <= 3)
233 : {
234 20475955 : edge e;
235 20475955 : edge_iterator ei;
236 20475955 : rtx src = NULL_RTX;
237 20475955 : rtx dest = NULL_RTX;
238 :
239 : /* Iterate over each incoming edge and see if they
240 : all have the same implicit set. */
241 20476085 : FOR_EACH_EDGE (e, ei, bb->preds)
242 : {
243 : /* Skip the entry/exit block. */
244 20475955 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
245 : break;
246 :
247 : /* Verify this block ends with a suitable condjump */
248 18472981 : rtx_insn *condjump = BB_END (e->src);
249 18472981 : if (!condjump || ! any_condjump_p (condjump))
250 : break;
251 :
252 : /* This predecessor ends with a possible equivalence
253 : producing conditional branch. Extract the condition
254 : and try to use it to create an equivalence. */
255 14411459 : rtx pat = pc_set (condjump);
256 14411459 : rtx i_t_e = SET_SRC (pat);
257 14411459 : gcc_assert (GET_CODE (i_t_e) == IF_THEN_ELSE);
258 14411459 : rtx cond = XEXP (i_t_e, 0);
259 :
260 14411459 : if ((((e->flags & EDGE_FALLTHRU) != 0)
261 14411459 : == (XEXP (i_t_e, 1) == pc_rtx))
262 14411459 : ? GET_CODE (cond) == EQ
263 8906523 : : GET_CODE (cond) == NE)
264 : {
265 : /* If this is the first time through record
266 : the source and destination. */
267 5623864 : if (!dest)
268 : {
269 5623864 : dest = XEXP (cond, 0);
270 5623864 : src = XEXP (cond, 1);
271 : }
272 : /* If this is not the first time through, then
273 : verify the source and destination match. */
274 0 : else if (rtx_equal_p (dest, XEXP (cond, 0))
275 0 : && rtx_equal_p (src, XEXP (cond, 1)))
276 : ;
277 : else
278 : break;
279 :
280 : /* A few more checks. First make sure we're dealing with
281 : integer modes, second make sure the values aren't clobbered
282 : by the conditional branch itself. Do this for every
283 : conditional jump participating in creation of the
284 : equivalence. */
285 5623864 : if (!REG_P (dest)
286 5623840 : || !(REG_P (src) || CONST_INT_P (src))
287 5623840 : || GET_MODE_CLASS (GET_MODE (dest)) != MODE_INT
288 130 : || reg_set_p (dest, condjump)
289 5623994 : || reg_set_p (src, condjump))
290 : break;
291 :
292 : }
293 : else
294 : break;
295 : }
296 :
297 : /* If all the incoming edges had the same implicit
298 : set, then create a dummy insn for that set.
299 :
300 : It will be entered into the cselib tables before
301 : we process the first real insn in this block. */
302 20475955 : if (dest && ei_end_p (ei))
303 130 : implicit_set = make_insn_raw (gen_rtx_SET (dest, src));
304 : }
305 :
306 271376859 : FOR_BB_INSNS (bb, insn)
307 : {
308 250376511 : if (INSN_P (insn))
309 : {
310 : /* If we recorded an implicit set, enter it
311 : into the tables before the first real insn.
312 :
313 : We have to do it this way because a CODE_LABEL
314 : will flush the cselib tables. */
315 206503026 : if (implicit_set)
316 : {
317 130 : cselib_process_insn (implicit_set);
318 130 : implicit_set = NULL;
319 : }
320 206503026 : cfg_changed |= reload_cse_simplify (insn, testreg);
321 : }
322 :
323 250376511 : cselib_process_insn (insn);
324 : }
325 : }
326 :
327 : /* Clean up. */
328 2003033 : end_alias_analysis ();
329 2003033 : cselib_finish ();
330 2003033 : if (cfg_changed)
331 78 : cleanup_cfg (0);
332 2003033 : }
333 :
334 : /* Try to simplify a single SET instruction. SET is the set pattern.
335 : INSN is the instruction it came from.
336 : This function only handles one case: if we set a register to a value
337 : which is not a register, we try to find that value in some other register
338 : and change the set into a register copy. */
339 :
340 : static int
341 101826339 : reload_cse_simplify_set (rtx set, rtx_insn *insn)
342 : {
343 101826339 : int did_change = 0;
344 101826339 : int dreg;
345 101826339 : rtx src;
346 101826339 : reg_class_t dclass;
347 101826339 : int old_cost;
348 101826339 : cselib_val *val;
349 101826339 : struct elt_loc_list *l;
350 101826339 : enum rtx_code extend_op = UNKNOWN;
351 101826339 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
352 :
353 101826339 : dreg = true_regnum (SET_DEST (set));
354 101826339 : if (dreg < 0)
355 : return 0;
356 :
357 68630217 : src = SET_SRC (set);
358 68630217 : if (side_effects_p (src) || true_regnum (src) >= 0)
359 10776079 : return 0;
360 :
361 57854138 : dclass = REGNO_REG_CLASS (dreg);
362 :
363 : /* When replacing a memory with a register, we need to honor assumptions
364 : that combine made wrt the contents of sign bits. We'll do this by
365 : generating an extend instruction instead of a reg->reg copy. Thus
366 : the destination must be a register that we can widen. */
367 57854138 : if (MEM_P (src)
368 : && (extend_op = load_extend_op (GET_MODE (src))) != UNKNOWN
369 : && !REG_P (SET_DEST (set)))
370 : return 0;
371 :
372 57854138 : val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
373 57854138 : if (! val)
374 : return 0;
375 :
376 : /* If memory loads are cheaper than register copies, don't change them. */
377 5625874 : if (MEM_P (src))
378 641942 : old_cost = memory_move_cost (GET_MODE (src), dclass, true);
379 4983932 : else if (REG_P (src))
380 0 : old_cost = register_move_cost (GET_MODE (src),
381 0 : REGNO_REG_CLASS (REGNO (src)), dclass);
382 : else
383 4983932 : old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
384 :
385 11194350 : for (l = val->locs; l; l = l->next)
386 : {
387 5568476 : rtx this_rtx = l->loc;
388 5568476 : int this_cost;
389 :
390 5568476 : if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx))
391 : {
392 1878676 : if (extend_op != UNKNOWN)
393 : {
394 : wide_int result;
395 :
396 : if (!CONST_SCALAR_INT_P (this_rtx))
397 : continue;
398 :
399 : switch (extend_op)
400 : {
401 : case ZERO_EXTEND:
402 : result = wide_int::from (rtx_mode_t (this_rtx,
403 : GET_MODE (src)),
404 : BITS_PER_WORD, UNSIGNED);
405 : break;
406 : case SIGN_EXTEND:
407 : result = wide_int::from (rtx_mode_t (this_rtx,
408 : GET_MODE (src)),
409 : BITS_PER_WORD, SIGNED);
410 : break;
411 : default:
412 : gcc_unreachable ();
413 : }
414 : this_rtx = immed_wide_int_const (result, word_mode);
415 : }
416 :
417 1878676 : this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
418 : }
419 3689800 : else if (REG_P (this_rtx))
420 : {
421 781018 : if (extend_op != UNKNOWN)
422 : {
423 : this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
424 : this_cost = set_src_cost (this_rtx, word_mode, speed);
425 : }
426 : else
427 781018 : this_cost = register_move_cost (GET_MODE (this_rtx),
428 781018 : REGNO_REG_CLASS (REGNO (this_rtx)),
429 : dclass);
430 : }
431 : else
432 2908782 : continue;
433 :
434 : /* If equal costs, prefer registers over anything else. That
435 : tends to lead to smaller instructions on some machines. */
436 2659694 : if (this_cost < old_cost
437 2508273 : || (this_cost == old_cost
438 1887818 : && REG_P (this_rtx)
439 15461 : && !REG_P (SET_SRC (set))))
440 : {
441 152315 : if (extend_op != UNKNOWN
442 : && REG_CAN_CHANGE_MODE_P (REGNO (SET_DEST (set)),
443 : GET_MODE (SET_DEST (set)), word_mode))
444 : {
445 : rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
446 : ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
447 : validate_change (insn, &SET_DEST (set), wide_dest, 1);
448 : }
449 :
450 152315 : validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
451 152315 : old_cost = this_cost, did_change = 1;
452 : }
453 : }
454 :
455 : return did_change;
456 : }
457 :
458 : /* Try to replace operands in INSN with equivalent values that are already
459 : in registers. This can be viewed as optional reloading.
460 :
461 : For each non-register operand in the insn, see if any hard regs are
462 : known to be equivalent to that operand. Record the alternatives which
463 : can accept these hard registers. Among all alternatives, select the
464 : ones which are better or equal to the one currently matching, where
465 : "better" is in terms of '?' and '!' constraints. Among the remaining
466 : alternatives, select the one which replaces most operands with
467 : hard registers. */
468 :
469 : static int
470 100790204 : reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
471 : {
472 100790204 : int i, j;
473 :
474 : /* For each operand, all registers that are equivalent to it. */
475 100790204 : HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
476 :
477 100790204 : const char *constraints[MAX_RECOG_OPERANDS];
478 :
479 : /* Vector recording how bad an alternative is. */
480 100790204 : int *alternative_reject;
481 : /* Vector recording how many registers can be introduced by choosing
482 : this alternative. */
483 100790204 : int *alternative_nregs;
484 : /* Array of vectors recording, for each operand and each alternative,
485 : which hard register to substitute, or -1 if the operand should be
486 : left as it is. */
487 100790204 : int *op_alt_regno[MAX_RECOG_OPERANDS];
488 : /* Array of alternatives, sorted in order of decreasing desirability. */
489 100790204 : int *alternative_order;
490 :
491 100790204 : extract_constrain_insn (insn);
492 :
493 100790204 : if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
494 : return 0;
495 :
496 87114277 : alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
497 87114277 : alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
498 87114277 : alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
499 87114277 : memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
500 87114277 : memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
501 :
502 : /* For each operand, find out which regs are equivalent. */
503 281561910 : for (i = 0; i < recog_data.n_operands; i++)
504 : {
505 : cselib_val *v;
506 : struct elt_loc_list *l;
507 : rtx op;
508 :
509 194447633 : CLEAR_HARD_REG_SET (equiv_regs[i]);
510 :
511 : /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem
512 : right, so avoid the problem here. Similarly NOTE_INSN_DELETED_LABEL.
513 : Likewise if we have a constant and the insn pattern doesn't tell us
514 : the mode we need. */
515 194447633 : if (LABEL_P (recog_data.operand[i])
516 194433479 : || (NOTE_P (recog_data.operand[i])
517 116 : && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
518 194433363 : || (CONSTANT_P (recog_data.operand[i])
519 33081183 : && recog_data.operand_mode[i] == VOIDmode))
520 582845 : continue;
521 :
522 193864788 : op = recog_data.operand[i];
523 193864788 : if (MEM_P (op) && load_extend_op (GET_MODE (op)) != UNKNOWN)
524 : {
525 : rtx set = single_set (insn);
526 :
527 : /* We might have multiple sets, some of which do implicit
528 : extension. Punt on this for now. */
529 : if (! set)
530 : continue;
531 : /* If the destination is also a MEM or a STRICT_LOW_PART, no
532 : extension applies.
533 : Also, if there is an explicit extension, we don't have to
534 : worry about an implicit one. */
535 : else if (MEM_P (SET_DEST (set))
536 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART
537 : || GET_CODE (SET_SRC (set)) == ZERO_EXTEND
538 : || GET_CODE (SET_SRC (set)) == SIGN_EXTEND)
539 : ; /* Continue ordinary processing. */
540 : /* If the register cannot change mode to word_mode, it follows that
541 : it cannot have been used in word_mode. */
542 : else if (REG_P (SET_DEST (set))
543 : && !REG_CAN_CHANGE_MODE_P (REGNO (SET_DEST (set)),
544 : GET_MODE (SET_DEST (set)),
545 : word_mode))
546 : ; /* Continue ordinary processing. */
547 : /* If this is a straight load, make the extension explicit. */
548 : else if (REG_P (SET_DEST (set))
549 : && recog_data.n_operands == 2
550 : && SET_SRC (set) == op
551 : && SET_DEST (set) == recog_data.operand[1-i])
552 : {
553 : validate_change (insn, recog_data.operand_loc[i],
554 : gen_rtx_fmt_e (load_extend_op (GET_MODE (op)),
555 : word_mode, op),
556 : 1);
557 : validate_change (insn, recog_data.operand_loc[1-i],
558 : gen_rtx_REG (word_mode, REGNO (SET_DEST (set))),
559 : 1);
560 : if (! apply_change_group ())
561 : return 0;
562 : return reload_cse_simplify_operands (insn, testreg);
563 : }
564 : else
565 : /* ??? There might be arithmetic operations with memory that are
566 : safe to optimize, but is it worth the trouble? */
567 : continue;
568 : }
569 :
570 193864788 : if (side_effects_p (op))
571 4548071 : continue;
572 189316717 : v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
573 189316717 : if (! v)
574 125361705 : continue;
575 :
576 188567317 : for (l = v->locs; l; l = l->next)
577 124612305 : if (REG_P (l->loc))
578 66380765 : SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
579 : }
580 :
581 87114277 : alternative_mask preferred = get_preferred_alternatives (insn);
582 281561910 : for (i = 0; i < recog_data.n_operands; i++)
583 : {
584 194447633 : machine_mode mode;
585 194447633 : int regno;
586 194447633 : const char *p;
587 :
588 194447633 : op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
589 2882321207 : for (j = 0; j < recog_data.n_alternatives; j++)
590 2687873574 : op_alt_regno[i][j] = -1;
591 :
592 194447633 : p = constraints[i] = recog_data.constraints[i];
593 194447633 : mode = recog_data.operand_mode[i];
594 :
595 : /* Add the reject values for each alternative given by the constraints
596 : for this operand. */
597 194447633 : j = 0;
598 7741953143 : while (*p != '\0')
599 : {
600 7547505510 : char c = *p++;
601 7547505510 : if (c == ',')
602 2484140362 : j++;
603 5063365148 : else if (c == '?')
604 606575225 : alternative_reject[j] += 3;
605 4456789923 : else if (c == '!')
606 18225200 : alternative_reject[j] += 300;
607 : }
608 :
609 : /* We won't change operands which are already registers. We
610 : also don't want to modify output operands. */
611 194447633 : regno = true_regnum (recog_data.operand[i]);
612 194447633 : if (regno >= 0
613 77736414 : || constraints[i][0] == '='
614 58354518 : || constraints[i][0] == '+')
615 136207564 : continue;
616 :
617 5416326417 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
618 : {
619 5358086348 : enum reg_class rclass = NO_REGS;
620 :
621 5358086348 : if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
622 5357364093 : continue;
623 :
624 722255 : set_mode_and_regno (testreg, mode, regno);
625 :
626 : /* We found a register equal to this operand. Now look for all
627 : alternatives that can accept this register and have not been
628 : assigned a register they can use yet. */
629 722255 : j = 0;
630 722255 : p = constraints[i];
631 39209620 : for (;;)
632 : {
633 39209620 : char c = *p;
634 :
635 39209620 : switch (c)
636 : {
637 188283 : case 'g':
638 188283 : rclass = reg_class_subunion[rclass][GENERAL_REGS];
639 188283 : break;
640 :
641 24804458 : default:
642 24804458 : rclass
643 24804458 : = (reg_class_subunion
644 24804458 : [rclass]
645 24804458 : [reg_class_for_constraint (lookup_constraint (p))]);
646 24804458 : break;
647 :
648 14216879 : case ',': case '\0':
649 : /* See if REGNO fits this alternative, and set it up as the
650 : replacement register if we don't have one for this
651 : alternative yet and the operand being replaced is not
652 : a cheap CONST_INT. */
653 14216879 : if (op_alt_regno[i][j] == -1
654 14148357 : && TEST_BIT (preferred, j)
655 9660344 : && reg_fits_class_p (testreg, rclass, 0, mode)
656 16583276 : && (!CONST_INT_P (recog_data.operand[i])
657 2233267 : || (set_src_cost (recog_data.operand[i], mode,
658 : optimize_bb_for_speed_p
659 2233267 : (BLOCK_FOR_INSN (insn)))
660 2233267 : > set_src_cost (testreg, mode,
661 : optimize_bb_for_speed_p
662 2233267 : (BLOCK_FOR_INSN (insn))))))
663 : {
664 133802 : alternative_nregs[j]++;
665 133802 : op_alt_regno[i][j] = regno;
666 : }
667 14216879 : j++;
668 14216879 : rclass = NO_REGS;
669 14216879 : break;
670 : }
671 39209620 : p += CONSTRAINT_LEN (c, p);
672 :
673 39209620 : if (c == '\0')
674 : break;
675 : }
676 : }
677 : }
678 :
679 : /* The loop below sets alternative_order[0] but -Wmaybe-uninitialized
680 : can't know that. Clear it here to avoid the warning. */
681 87114277 : alternative_order[0] = 0;
682 87114277 : gcc_assert (!recog_data.n_alternatives
683 : || (which_alternative >= 0
684 : && which_alternative < recog_data.n_alternatives));
685 :
686 : /* Record all alternatives which are better or equal to the currently
687 : matching one in the alternative_order array. */
688 1366387358 : for (i = j = 0; i < recog_data.n_alternatives; i++)
689 1279273081 : if (alternative_reject[i] <= alternative_reject[which_alternative])
690 746740516 : alternative_order[j++] = i;
691 87114277 : recog_data.n_alternatives = j;
692 :
693 : /* Sort it. Given a small number of alternatives, a dumb algorithm
694 : won't hurt too much. */
695 746740516 : for (i = 0; i < recog_data.n_alternatives - 1; i++)
696 : {
697 659626239 : int best = i;
698 659626239 : int best_reject = alternative_reject[alternative_order[i]];
699 659626239 : int best_nregs = alternative_nregs[alternative_order[i]];
700 :
701 4580579586 : for (j = i + 1; j < recog_data.n_alternatives; j++)
702 : {
703 3920953347 : int this_reject = alternative_reject[alternative_order[j]];
704 3920953347 : int this_nregs = alternative_nregs[alternative_order[j]];
705 :
706 3920953347 : if (this_reject < best_reject
707 3914307606 : || (this_reject == best_reject && this_nregs > best_nregs))
708 : {
709 6723806 : best = j;
710 6723806 : best_reject = this_reject;
711 6723806 : best_nregs = this_nregs;
712 : }
713 : }
714 :
715 659626239 : std::swap (alternative_order[best], alternative_order[i]);
716 : }
717 :
718 : /* Substitute the operands as determined by op_alt_regno for the best
719 : alternative. */
720 87114277 : j = alternative_order[0];
721 :
722 281561910 : for (i = 0; i < recog_data.n_operands; i++)
723 : {
724 194447633 : machine_mode mode = recog_data.operand_mode[i];
725 194447633 : if (op_alt_regno[i][j] == -1)
726 194397718 : continue;
727 :
728 49915 : validate_change (insn, recog_data.operand_loc[i],
729 : gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
730 : }
731 :
732 88429822 : for (i = recog_data.n_dups - 1; i >= 0; i--)
733 : {
734 1315545 : int op = recog_data.dup_num[i];
735 1315545 : machine_mode mode = recog_data.operand_mode[op];
736 :
737 1315545 : if (op_alt_regno[op][j] == -1)
738 1315136 : continue;
739 :
740 409 : validate_change (insn, recog_data.dup_loc[i],
741 : gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
742 : }
743 :
744 87114277 : return apply_change_group ();
745 : }
746 :
747 : /* If reload couldn't use reg+reg+offset addressing, try to use reg+reg
748 : addressing now.
749 : This code might also be useful when reload gave up on reg+reg addressing
750 : because of clashes between the return register and INDEX_REG_CLASS. */
751 :
752 : /* The maximum number of uses of a register we can keep track of to
753 : replace them with reg+reg addressing. */
754 : #define RELOAD_COMBINE_MAX_USES 16
755 :
756 : /* Describes a recorded use of a register. */
757 : struct reg_use
758 : {
759 : /* The insn where a register has been used. */
760 : rtx_insn *insn;
761 : /* Points to the memory reference enclosing the use, if any, NULL_RTX
762 : otherwise. */
763 : rtx containing_mem;
764 : /* Location of the register within INSN. */
765 : rtx *usep;
766 : /* The reverse uid of the insn. */
767 : int ruid;
768 : };
769 :
770 : /* If the register is used in some unknown fashion, USE_INDEX is negative.
771 : If it is dead, USE_INDEX is RELOAD_COMBINE_MAX_USES, and STORE_RUID
772 : indicates where it is first set or clobbered.
773 : Otherwise, USE_INDEX is the index of the last encountered use of the
774 : register (which is first among these we have seen since we scan backwards).
775 : USE_RUID indicates the first encountered, i.e. last, of these uses.
776 : If ALL_OFFSETS_MATCH is true, all encountered uses were inside a PLUS
777 : with a constant offset; OFFSET contains this constant in that case.
778 : STORE_RUID is always meaningful if we only want to use a value in a
779 : register in a different place: it denotes the next insn in the insn
780 : stream (i.e. the last encountered) that sets or clobbers the register.
781 : REAL_STORE_RUID is similar, but clobbers are ignored when updating it.
782 : EXPR is the expression used when storing the register. */
783 : static struct
784 : {
785 : struct reg_use reg_use[RELOAD_COMBINE_MAX_USES];
786 : rtx offset;
787 : int use_index;
788 : int store_ruid;
789 : int real_store_ruid;
790 : int use_ruid;
791 : bool all_offsets_match;
792 : rtx expr;
793 : } reg_state[FIRST_PSEUDO_REGISTER];
794 :
795 : /* Reverse linear uid. This is increased in reload_combine while scanning
796 : the instructions from last to first. It is used to set last_label_ruid
797 : and the store_ruid / use_ruid fields in reg_state. */
798 : static int reload_combine_ruid;
799 :
800 : /* The RUID of the last label we encountered in reload_combine. */
801 : static int last_label_ruid;
802 :
803 : /* The RUID of the last jump we encountered in reload_combine. */
804 : static int last_jump_ruid;
805 :
806 : /* The register numbers of the first and last index register. A value of
807 : -1 in LAST_INDEX_REG indicates that we've previously computed these
808 : values and found no suitable index registers. */
809 : static int first_index_reg = -1;
810 : static int last_index_reg;
811 :
812 : #define LABEL_LIVE(LABEL) \
813 : (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
814 :
815 : /* Subroutine of reload_combine_split_ruids, called to fix up a single
816 : ruid pointed to by *PRUID if it is higher than SPLIT_RUID. */
817 :
818 : static inline void
819 221124 : reload_combine_split_one_ruid (int *pruid, int split_ruid)
820 : {
821 221124 : if (*pruid > split_ruid)
822 9140 : (*pruid)++;
823 : }
824 :
825 : /* Called when we insert a new insn in a position we've already passed in
826 : the scan. Examine all our state, increasing all ruids that are higher
827 : than SPLIT_RUID by one in order to make room for a new insn. */
828 :
829 : static void
830 782 : reload_combine_split_ruids (int split_ruid)
831 : {
832 782 : unsigned i;
833 :
834 782 : reload_combine_split_one_ruid (&reload_combine_ruid, split_ruid);
835 782 : reload_combine_split_one_ruid (&last_label_ruid, split_ruid);
836 782 : reload_combine_split_one_ruid (&last_jump_ruid, split_ruid);
837 :
838 72726 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
839 : {
840 71944 : int j, idx = reg_state[i].use_index;
841 71944 : reload_combine_split_one_ruid (®_state[i].use_ruid, split_ruid);
842 71944 : reload_combine_split_one_ruid (®_state[i].store_ruid, split_ruid);
843 71944 : reload_combine_split_one_ruid (®_state[i].real_store_ruid,
844 : split_ruid);
845 71944 : if (idx < 0)
846 25733 : continue;
847 49157 : for (j = idx; j < RELOAD_COMBINE_MAX_USES; j++)
848 : {
849 5209 : reload_combine_split_one_ruid (®_state[i].reg_use[j].ruid,
850 : split_ruid);
851 : }
852 : }
853 782 : }
854 :
855 : /* Called when we are about to rescan a previously encountered insn with
856 : reload_combine_note_use after modifying some part of it. This clears all
857 : information about uses in that particular insn. */
858 :
859 : static void
860 5539 : reload_combine_purge_insn_uses (rtx_insn *insn)
861 : {
862 5539 : unsigned i;
863 :
864 515127 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
865 : {
866 509588 : int j, k, idx = reg_state[i].use_index;
867 509588 : if (idx < 0)
868 88918 : continue;
869 : j = k = RELOAD_COMBINE_MAX_USES;
870 462703 : while (j-- > idx)
871 : {
872 42033 : if (reg_state[i].reg_use[j].insn != insn)
873 : {
874 35998 : k--;
875 35998 : if (k != j)
876 4178 : reg_state[i].reg_use[k] = reg_state[i].reg_use[j];
877 : }
878 : }
879 420670 : reg_state[i].use_index = k;
880 : }
881 5539 : }
882 :
883 : /* Called when we need to forget about all uses of REGNO after an insn
884 : which is identified by RUID. */
885 :
886 : static void
887 782 : reload_combine_purge_reg_uses_after_ruid (unsigned regno, int ruid)
888 : {
889 782 : int j, k, idx = reg_state[regno].use_index;
890 782 : if (idx < 0)
891 : return;
892 : j = k = RELOAD_COMBINE_MAX_USES;
893 3030 : while (j-- > idx)
894 : {
895 2248 : if (reg_state[regno].reg_use[j].ruid >= ruid)
896 : {
897 1311 : k--;
898 1311 : if (k != j)
899 532 : reg_state[regno].reg_use[k] = reg_state[regno].reg_use[j];
900 : }
901 : }
902 782 : reg_state[regno].use_index = k;
903 : }
904 :
905 : /* Find the use of REGNO with the ruid that is highest among those
906 : lower than RUID_LIMIT, and return it if it is the only use of this
907 : reg in the insn. Return NULL otherwise. */
908 :
909 : static struct reg_use *
910 3778174 : reload_combine_closest_single_use (unsigned regno, int ruid_limit)
911 : {
912 3778174 : int i, best_ruid = 0;
913 3778174 : int use_idx = reg_state[regno].use_index;
914 3778174 : struct reg_use *retval;
915 :
916 3778174 : if (use_idx < 0)
917 : return NULL;
918 : retval = NULL;
919 3698272 : for (i = use_idx; i < RELOAD_COMBINE_MAX_USES; i++)
920 : {
921 2142855 : struct reg_use *use = reg_state[regno].reg_use + i;
922 2142855 : int this_ruid = use->ruid;
923 2142855 : if (this_ruid >= ruid_limit)
924 815366 : continue;
925 1327489 : if (this_ruid > best_ruid)
926 : {
927 : best_ruid = this_ruid;
928 : retval = use;
929 : }
930 348067 : else if (this_ruid == best_ruid)
931 2142855 : retval = NULL;
932 : }
933 1555417 : if (last_label_ruid >= best_ruid)
934 649813 : return NULL;
935 : return retval;
936 : }
937 :
938 : /* After we've moved an add insn, fix up any debug insns that occur
939 : between the old location of the add and the new location. REG is
940 : the destination register of the add insn; REPLACEMENT is the
941 : SET_SRC of the add. FROM and TO specify the range in which we
942 : should make this change on debug insns. */
943 :
944 : static void
945 954 : fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
946 : {
947 954 : rtx_insn *insn;
948 7393 : for (insn = from; insn != to; insn = NEXT_INSN (insn))
949 : {
950 6439 : rtx t;
951 :
952 6439 : if (!DEBUG_BIND_INSN_P (insn))
953 5246 : continue;
954 :
955 1193 : t = INSN_VAR_LOCATION_LOC (insn);
956 1193 : t = simplify_replace_rtx (t, reg, replacement);
957 1193 : validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0);
958 : }
959 954 : }
960 :
961 : /* Subroutine of reload_combine_recognize_const_pattern. Try to replace REG
962 : with SRC in the insn described by USE, taking costs into account. Return
963 : true if we made the replacement. */
964 :
965 : static bool
966 778997 : try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
967 : {
968 778997 : rtx_insn *use_insn = use->insn;
969 778997 : rtx mem = use->containing_mem;
970 778997 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
971 :
972 778997 : if (mem != NULL_RTX)
973 : {
974 17468 : addr_space_t as = MEM_ADDR_SPACE (mem);
975 17468 : rtx oldaddr = XEXP (mem, 0);
976 17468 : rtx newaddr = NULL_RTX;
977 17468 : int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed);
978 17468 : int new_cost;
979 :
980 17468 : newaddr = simplify_replace_rtx (oldaddr, reg, src);
981 17468 : if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as))
982 : {
983 5163 : XEXP (mem, 0) = newaddr;
984 5163 : new_cost = address_cost (newaddr, GET_MODE (mem), as, speed);
985 5163 : XEXP (mem, 0) = oldaddr;
986 5163 : if (new_cost <= old_cost
987 5163 : && validate_change (use_insn,
988 : &XEXP (mem, 0), newaddr, 0))
989 : return true;
990 : }
991 : }
992 : else
993 : {
994 761529 : rtx new_set = single_set (use_insn);
995 761529 : if (new_set
996 760591 : && REG_P (SET_DEST (new_set))
997 309494 : && GET_CODE (SET_SRC (new_set)) == PLUS
998 21556 : && REG_P (XEXP (SET_SRC (new_set), 0))
999 19597 : && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
1000 : {
1001 1524 : rtx new_src;
1002 1524 : machine_mode mode = GET_MODE (SET_DEST (new_set));
1003 1524 : int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
1004 :
1005 1524 : gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
1006 1524 : new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
1007 :
1008 1524 : if (set_src_cost (new_src, mode, speed) <= old_cost
1009 1524 : && validate_change (use_insn, &SET_SRC (new_set),
1010 : new_src, 0))
1011 : return true;
1012 : }
1013 : }
1014 : return false;
1015 : }
1016 :
1017 : /* Called by reload_combine when scanning INSN. This function tries to detect
1018 : patterns where a constant is added to a register, and the result is used
1019 : in an address.
1020 : Return true if no further processing is needed on INSN; false if it wasn't
1021 : recognized and should be handled normally. */
1022 :
1023 : static bool
1024 61383294 : reload_combine_recognize_const_pattern (rtx_insn *insn)
1025 : {
1026 61383294 : int from_ruid = reload_combine_ruid;
1027 61383294 : rtx set, pat, reg, src, addreg;
1028 61383294 : unsigned int regno;
1029 61383294 : struct reg_use *use;
1030 61383294 : bool must_move_add;
1031 61383294 : rtx_insn *add_moved_after_insn = NULL;
1032 61383294 : int add_moved_after_ruid = 0;
1033 61383294 : int clobbered_regno = -1;
1034 :
1035 61383294 : set = single_set (insn);
1036 61383294 : if (set == NULL_RTX)
1037 : return false;
1038 :
1039 57230384 : reg = SET_DEST (set);
1040 57230384 : src = SET_SRC (set);
1041 57230384 : if (!REG_P (reg)
1042 38978440 : || REG_NREGS (reg) != 1
1043 44672738 : || GET_MODE (reg) != Pmode
1044 79384897 : || reg == stack_pointer_rtx)
1045 : return false;
1046 :
1047 20448086 : regno = REGNO (reg);
1048 :
1049 : /* We look for a REG1 = REG2 + CONSTANT insn, followed by either
1050 : uses of REG1 inside an address, or inside another add insn. If
1051 : possible and profitable, merge the addition into subsequent
1052 : uses. */
1053 20448086 : if (GET_CODE (src) != PLUS
1054 4012288 : || !REG_P (XEXP (src, 0))
1055 3742988 : || !CONSTANT_P (XEXP (src, 1)))
1056 : return false;
1057 :
1058 3094177 : addreg = XEXP (src, 0);
1059 3094177 : must_move_add = rtx_equal_p (reg, addreg);
1060 :
1061 3094177 : pat = PATTERN (insn);
1062 3094177 : if (must_move_add && set != pat)
1063 : {
1064 : /* We have to be careful when moving the add; apart from the
1065 : single_set there may also be clobbers. Recognize one special
1066 : case, that of one clobber alongside the set (likely a clobber
1067 : of the CC register). */
1068 820067 : gcc_assert (GET_CODE (PATTERN (insn)) == PARALLEL);
1069 820067 : if (XVECLEN (pat, 0) != 2 || XVECEXP (pat, 0, 0) != set
1070 820067 : || GET_CODE (XVECEXP (pat, 0, 1)) != CLOBBER
1071 820067 : || !REG_P (XEXP (XVECEXP (pat, 0, 1), 0)))
1072 : return false;
1073 820067 : clobbered_regno = REGNO (XEXP (XVECEXP (pat, 0, 1), 0));
1074 : }
1075 :
1076 3778174 : do
1077 : {
1078 3778174 : use = reload_combine_closest_single_use (regno, from_ruid);
1079 :
1080 3778174 : if (use)
1081 : /* Start the search for the next use from here. */
1082 881586 : from_ruid = use->ruid;
1083 :
1084 1237418 : if (use && GET_MODE (*use->usep) == Pmode)
1085 : {
1086 875555 : bool delete_add = false;
1087 875555 : rtx_insn *use_insn = use->insn;
1088 875555 : int use_ruid = use->ruid;
1089 :
1090 : /* Avoid moving the add insn past a jump. */
1091 875555 : if (must_move_add && use_ruid <= last_jump_ruid)
1092 : break;
1093 :
1094 : /* If the add clobbers another hard reg in parallel, don't move
1095 : it past a real set of this hard reg. */
1096 875262 : if (must_move_add && clobbered_regno >= 0
1097 114913 : && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1098 : break;
1099 :
1100 849677 : gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1101 : /* Avoid moving a use of ADDREG past a point where it is stored. */
1102 849677 : if (reg_state[REGNO (addreg)].store_ruid > use_ruid)
1103 : break;
1104 :
1105 : /* We also must not move the addition past an insn that sets
1106 : the same register, unless we can combine two add insns. */
1107 779003 : if (must_move_add && reg_state[regno].store_ruid == use_ruid)
1108 : {
1109 29556 : if (use->containing_mem == NULL_RTX)
1110 : delete_add = true;
1111 : else
1112 : break;
1113 : }
1114 :
1115 778997 : if (try_replace_in_use (use, reg, src))
1116 : {
1117 5539 : reload_combine_purge_insn_uses (use_insn);
1118 5539 : reload_combine_note_use (&PATTERN (use_insn), use_insn,
1119 : use_ruid, NULL_RTX);
1120 :
1121 5539 : if (delete_add)
1122 : {
1123 55 : fixup_debug_insns (reg, src, insn, use_insn);
1124 55 : delete_insn (insn);
1125 55 : return true;
1126 : }
1127 5484 : if (must_move_add)
1128 : {
1129 1575 : add_moved_after_insn = use_insn;
1130 1575 : add_moved_after_ruid = use_ruid;
1131 : }
1132 5484 : continue;
1133 : }
1134 : }
1135 : /* If we get here, we couldn't handle this use. */
1136 3676077 : if (must_move_add)
1137 : break;
1138 : }
1139 2857557 : while (use);
1140 :
1141 3094122 : if (!must_move_add || add_moved_after_insn == NULL_RTX)
1142 : /* Process the add normally. */
1143 : return false;
1144 :
1145 782 : fixup_debug_insns (reg, src, insn, add_moved_after_insn);
1146 :
1147 782 : reorder_insns (insn, insn, add_moved_after_insn);
1148 782 : reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
1149 782 : reload_combine_split_ruids (add_moved_after_ruid - 1);
1150 782 : reload_combine_note_use (&PATTERN (insn), insn,
1151 : add_moved_after_ruid, NULL_RTX);
1152 782 : reg_state[regno].store_ruid = add_moved_after_ruid;
1153 :
1154 782 : return true;
1155 : }
1156 :
1157 : /* Called by reload_combine when scanning INSN. Try to detect a pattern we
1158 : can handle and improve. Return true if no further processing is needed on
1159 : INSN; false if it wasn't recognized and should be handled normally. */
1160 :
1161 : static bool
1162 61382457 : reload_combine_recognize_pattern (rtx_insn *insn)
1163 : {
1164 61382457 : rtx set, reg, src;
1165 :
1166 61382457 : set = single_set (insn);
1167 61382457 : if (set == NULL_RTX)
1168 : return false;
1169 :
1170 57229547 : reg = SET_DEST (set);
1171 57229547 : src = SET_SRC (set);
1172 57229547 : if (!REG_P (reg) || REG_NREGS (reg) != 1)
1173 : return false;
1174 :
1175 38362970 : unsigned int regno = REGNO (reg);
1176 38362970 : machine_mode mode = GET_MODE (reg);
1177 :
1178 38362970 : if (reg_state[regno].use_index < 0
1179 38362970 : || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1180 : return false;
1181 :
1182 24872937 : for (int i = reg_state[regno].use_index;
1183 45444366 : i < RELOAD_COMBINE_MAX_USES; i++)
1184 : {
1185 25664236 : struct reg_use *use = reg_state[regno].reg_use + i;
1186 25664236 : if (GET_MODE (*use->usep) != mode)
1187 : return false;
1188 : /* Don't try to adjust (use (REGX)). */
1189 24876652 : if (GET_CODE (PATTERN (use->insn)) == USE
1190 24876652 : && &XEXP (PATTERN (use->insn), 0) == use->usep)
1191 : return false;
1192 : }
1193 :
1194 : /* Look for (set (REGX) (CONST_INT))
1195 : (set (REGX) (PLUS (REGX) (REGY)))
1196 : ...
1197 : ... (MEM (REGX)) ...
1198 : and convert it to
1199 : (set (REGZ) (CONST_INT))
1200 : ...
1201 : ... (MEM (PLUS (REGZ) (REGY)))... .
1202 :
1203 : First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
1204 : and that we know all uses of REGX before it dies.
1205 : Also, explicitly check that REGX != REGY; our life information
1206 : does not yet show whether REGY changes in this insn. */
1207 :
1208 19780130 : if (GET_CODE (src) == PLUS
1209 2366527 : && reg_state[regno].all_offsets_match
1210 2091602 : && last_index_reg != -1
1211 2091602 : && REG_P (XEXP (src, 1))
1212 689511 : && rtx_equal_p (XEXP (src, 0), reg)
1213 498374 : && !rtx_equal_p (XEXP (src, 1), reg)
1214 20271330 : && last_label_ruid < reg_state[regno].use_ruid)
1215 : {
1216 459013 : rtx base = XEXP (src, 1);
1217 459013 : rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1218 459013 : rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1219 459013 : rtx index_reg = NULL_RTX;
1220 459013 : rtx reg_sum = NULL_RTX;
1221 459013 : int i;
1222 :
1223 : /* Now we need to set INDEX_REG to an index register (denoted as
1224 : REGZ in the illustration above) and REG_SUM to the expression
1225 : register+register that we want to use to substitute uses of REG
1226 : (typically in MEMs) with. First check REG and BASE for being
1227 : index registers; we can use them even if they are not dead. */
1228 459013 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
1229 459013 : || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
1230 : REGNO (base)))
1231 : {
1232 : index_reg = reg;
1233 : reg_sum = src;
1234 : }
1235 : else
1236 : {
1237 : /* Otherwise, look for a free index register. Since we have
1238 : checked above that neither REG nor BASE are index registers,
1239 : if we find anything at all, it will be different from these
1240 : two registers. */
1241 8486447 : for (i = first_index_reg; i <= last_index_reg; i++)
1242 : {
1243 8401431 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
1244 2937142 : && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1245 1690391 : && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1246 1675495 : && (crtl->abi->clobbers_full_reg_p (i)
1247 324271 : || df_regs_ever_live_p (i))
1248 1430417 : && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1249 1429389 : && !fixed_regs[i] && !global_regs[i]
1250 528845 : && hard_regno_nregs (i, GET_MODE (reg)) == 1
1251 8536223 : && targetm.hard_regno_scratch_ok (i))
1252 : {
1253 134792 : index_reg = gen_rtx_REG (GET_MODE (reg), i);
1254 134792 : reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1255 134792 : break;
1256 : }
1257 : }
1258 : }
1259 :
1260 : /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
1261 : (REGY), i.e. BASE, is not clobbered before the last use we'll
1262 : create. */
1263 459013 : if (reg_sum
1264 459013 : && prev_set
1265 367606 : && CONST_INT_P (SET_SRC (prev_set))
1266 8515 : && rtx_equal_p (SET_DEST (prev_set), reg)
1267 459013 : && (reg_state[REGNO (base)].store_ruid
1268 3430 : <= reg_state[regno].use_ruid))
1269 : {
1270 : /* Change destination register and, if necessary, the constant
1271 : value in PREV, the constant loading instruction. */
1272 3337 : validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
1273 3337 : if (reg_state[regno].offset != const0_rtx)
1274 : {
1275 0 : HOST_WIDE_INT c
1276 0 : = trunc_int_for_mode (UINTVAL (SET_SRC (prev_set))
1277 0 : + UINTVAL (reg_state[regno].offset),
1278 0 : GET_MODE (index_reg));
1279 0 : validate_change (prev, &SET_SRC (prev_set), GEN_INT (c), 1);
1280 : }
1281 :
1282 : /* Now for every use of REG that we have recorded, replace REG
1283 : with REG_SUM. */
1284 6742 : for (i = reg_state[regno].use_index;
1285 6742 : i < RELOAD_COMBINE_MAX_USES; i++)
1286 3405 : validate_unshare_change (reg_state[regno].reg_use[i].insn,
1287 : reg_state[regno].reg_use[i].usep,
1288 : /* Each change must have its own
1289 : replacement. */
1290 : reg_sum, 1);
1291 :
1292 3337 : if (apply_change_group ())
1293 : {
1294 117 : struct reg_use *lowest_ruid = NULL;
1295 :
1296 : /* For every new use of REG_SUM, we have to record the use
1297 : of BASE therein, i.e. operand 1. */
1298 254 : for (i = reg_state[regno].use_index;
1299 254 : i < RELOAD_COMBINE_MAX_USES; i++)
1300 : {
1301 137 : struct reg_use *use = reg_state[regno].reg_use + i;
1302 137 : reload_combine_note_use (&XEXP (*use->usep, 1), use->insn,
1303 : use->ruid, use->containing_mem);
1304 137 : if (lowest_ruid == NULL || use->ruid < lowest_ruid->ruid)
1305 137 : lowest_ruid = use;
1306 : }
1307 :
1308 117 : fixup_debug_insns (reg, reg_sum, insn, lowest_ruid->insn);
1309 :
1310 : /* Delete the reg-reg addition. */
1311 117 : delete_insn (insn);
1312 :
1313 117 : if (reg_state[regno].offset != const0_rtx)
1314 : /* Previous REG_EQUIV / REG_EQUAL notes for PREV
1315 : are now invalid. */
1316 0 : remove_reg_equal_equiv_notes (prev);
1317 :
1318 117 : reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
1319 117 : return true;
1320 : }
1321 : }
1322 : }
1323 : return false;
1324 : }
1325 :
1326 : static void
1327 1051051 : reload_combine (void)
1328 : {
1329 1051051 : rtx_insn *insn, *prev;
1330 1051051 : basic_block bb;
1331 1051051 : unsigned int r;
1332 1051051 : int min_labelno, n_labels;
1333 1051051 : HARD_REG_SET ever_live_at_start, *label_live;
1334 :
1335 : /* To avoid wasting too much time later searching for an index register,
1336 : determine the minimum and maximum index register numbers. */
1337 1051051 : if (INDEX_REG_CLASS == NO_REGS)
1338 : last_index_reg = -1;
1339 1051051 : else if (first_index_reg == -1 && last_index_reg == 0)
1340 : {
1341 145119 : hard_reg_set_iterator hrsi1;
1342 4643808 : EXECUTE_IF_SET_IN_HARD_REG_SET
1343 : (reg_class_contents[INDEX_REG_CLASS], 0, r, hrsi1)
1344 : {
1345 4498689 : if (first_index_reg == -1)
1346 145119 : first_index_reg = r;
1347 :
1348 4498689 : last_index_reg = r;
1349 : }
1350 :
1351 : /* If no index register is available, we can quit now. Set LAST_INDEX_REG
1352 : to -1 so we'll know to quit early the next time we get here. */
1353 145119 : if (first_index_reg == -1)
1354 : {
1355 0 : last_index_reg = -1;
1356 0 : return;
1357 : }
1358 : }
1359 :
1360 : /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
1361 : information is a bit fuzzy immediately after reload, but it's
1362 : still good enough to determine which registers are live at a jump
1363 : destination. */
1364 1051051 : min_labelno = get_first_label_num ();
1365 1051051 : n_labels = max_label_num () - min_labelno;
1366 1051051 : label_live = XNEWVEC (HARD_REG_SET, n_labels);
1367 1051051 : CLEAR_HARD_REG_SET (ever_live_at_start);
1368 :
1369 12585708 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
1370 : {
1371 11534657 : insn = BB_HEAD (bb);
1372 11534657 : if (LABEL_P (insn))
1373 : {
1374 5360586 : HARD_REG_SET live;
1375 5360586 : bitmap live_in = df_get_live_in (bb);
1376 :
1377 10721172 : REG_SET_TO_HARD_REG_SET (live, live_in);
1378 5360586 : compute_use_by_pseudos (&live, live_in);
1379 5360586 : LABEL_LIVE (insn) = live;
1380 10721172 : ever_live_at_start |= live;
1381 : }
1382 : }
1383 :
1384 : /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
1385 1051051 : last_label_ruid = last_jump_ruid = reload_combine_ruid = 0;
1386 97747743 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1387 : {
1388 96696692 : reg_state[r].store_ruid = 0;
1389 96696692 : reg_state[r].real_store_ruid = 0;
1390 96696692 : if (fixed_regs[r])
1391 47869472 : reg_state[r].use_index = -1;
1392 : else
1393 48827220 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1394 : }
1395 :
1396 143916978 : for (insn = get_last_insn (); insn; insn = prev)
1397 : {
1398 142865927 : bool control_flow_insn;
1399 142865927 : rtx note;
1400 :
1401 142865927 : prev = PREV_INSN (insn);
1402 :
1403 : /* We cannot do our optimization across labels. Invalidating all the use
1404 : information we have would be costly, so we just note where the label
1405 : is and then later disable any optimization that would cross it. */
1406 142865927 : if (LABEL_P (insn))
1407 5367947 : last_label_ruid = reload_combine_ruid;
1408 137497980 : else if (BARRIER_P (insn))
1409 : {
1410 : /* Crossing a barrier resets all the use information. */
1411 287204460 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1412 284116240 : if (! fixed_regs[r])
1413 138538969 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1414 : }
1415 134409760 : else if (INSN_P (insn) && volatile_insn_p (PATTERN (insn)))
1416 : /* Optimizations across insns being marked as volatile must be
1417 : prevented. All the usage information is invalidated
1418 : here. */
1419 42358989 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1420 41903516 : if (! fixed_regs[r]
1421 19720209 : && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1422 672264 : reg_state[r].use_index = -1;
1423 :
1424 142865927 : if (! NONDEBUG_INSN_P (insn))
1425 81482633 : continue;
1426 :
1427 61383294 : reload_combine_ruid++;
1428 :
1429 61383294 : control_flow_insn = control_flow_insn_p (insn);
1430 61383294 : if (control_flow_insn)
1431 8833769 : last_jump_ruid = reload_combine_ruid;
1432 :
1433 61383294 : if (reload_combine_recognize_const_pattern (insn)
1434 61383294 : || reload_combine_recognize_pattern (insn))
1435 954 : continue;
1436 :
1437 61382340 : note_stores (insn, reload_combine_note_store, NULL);
1438 :
1439 61382340 : if (CALL_P (insn))
1440 : {
1441 4893417 : rtx link;
1442 4893417 : HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
1443 :
1444 4893417 : hard_reg_set_iterator hrsi2;
1445 404121919 : EXECUTE_IF_SET_IN_HARD_REG_SET (used_regs, 0, r, hrsi2)
1446 : {
1447 399228502 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1448 399228502 : reg_state[r].store_ruid = reload_combine_ruid;
1449 : }
1450 :
1451 15267369 : for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1452 10373952 : link = XEXP (link, 1))
1453 : {
1454 10373952 : rtx setuse = XEXP (link, 0);
1455 10373952 : rtx usage_rtx = XEXP (setuse, 0);
1456 :
1457 10373952 : if (GET_CODE (setuse) == USE && REG_P (usage_rtx))
1458 : {
1459 8969863 : unsigned int end_regno = END_REGNO (usage_rtx);
1460 17995495 : for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1461 9025632 : reg_state[i].use_index = -1;
1462 : }
1463 : }
1464 : }
1465 :
1466 61382340 : if (control_flow_insn && !ANY_RETURN_P (PATTERN (insn)))
1467 : {
1468 : /* Non-spill registers might be used at the call destination in
1469 : some unknown fashion, so we have to mark the unknown use. */
1470 8833769 : HARD_REG_SET *live;
1471 :
1472 10253487 : if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1473 8833852 : && JUMP_LABEL (insn))
1474 : {
1475 7414134 : if (ANY_RETURN_P (JUMP_LABEL (insn)))
1476 : live = NULL;
1477 : else
1478 7414134 : live = &LABEL_LIVE (JUMP_LABEL (insn));
1479 : }
1480 : else
1481 : live = &ever_live_at_start;
1482 :
1483 7414134 : if (live)
1484 : {
1485 8833769 : hard_reg_set_iterator hrsi3;
1486 53207972 : EXECUTE_IF_SET_IN_HARD_REG_SET (*live, 0, r, hrsi3)
1487 44374203 : reg_state[r].use_index = -1;
1488 : }
1489 : }
1490 :
1491 61382340 : reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1492 : NULL_RTX);
1493 :
1494 85488311 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1495 : {
1496 24105971 : if (REG_NOTE_KIND (note) == REG_INC && REG_P (XEXP (note, 0)))
1497 : {
1498 0 : int regno = REGNO (XEXP (note, 0));
1499 0 : reg_state[regno].store_ruid = reload_combine_ruid;
1500 0 : reg_state[regno].real_store_ruid = reload_combine_ruid;
1501 0 : reg_state[regno].use_index = -1;
1502 : }
1503 : }
1504 : }
1505 :
1506 1051051 : free (label_live);
1507 : }
1508 :
1509 : /* Check if DST is a register or a subreg of a register; if it is,
1510 : update store_ruid, real_store_ruid and use_index in the reg_state
1511 : structure accordingly. Called via note_stores from reload_combine. */
1512 :
1513 : static void
1514 66034918 : reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1515 : {
1516 66034918 : int regno = 0;
1517 66034918 : int i;
1518 66034918 : machine_mode mode = GET_MODE (dst);
1519 :
1520 66034918 : if (GET_CODE (dst) == SUBREG)
1521 : {
1522 7422 : regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1523 3711 : GET_MODE (SUBREG_REG (dst)),
1524 3711 : SUBREG_BYTE (dst),
1525 : GET_MODE (dst));
1526 3711 : dst = SUBREG_REG (dst);
1527 : }
1528 :
1529 : /* Some targets do argument pushes without adding REG_INC notes. */
1530 :
1531 66034918 : if (MEM_P (dst))
1532 : {
1533 10934912 : dst = XEXP (dst, 0);
1534 10934912 : if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1535 10934912 : || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1536 9290008 : || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1537 : {
1538 1714847 : unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1539 3429694 : for (unsigned int i = REGNO (XEXP (dst, 0)); i < end_regno; ++i)
1540 : {
1541 : /* We could probably do better, but for now mark the register
1542 : as used in an unknown fashion and set/clobbered at this
1543 : insn. */
1544 1714847 : reg_state[i].use_index = -1;
1545 1714847 : reg_state[i].store_ruid = reload_combine_ruid;
1546 1714847 : reg_state[i].real_store_ruid = reload_combine_ruid;
1547 : }
1548 : }
1549 : else
1550 : return;
1551 : }
1552 :
1553 56814853 : if (!REG_P (dst))
1554 : return;
1555 47672875 : regno += REGNO (dst);
1556 :
1557 : /* note_stores might have stripped a STRICT_LOW_PART, so we have to be
1558 : careful with registers / register parts that are not full words.
1559 : Similarly for ZERO_EXTRACT. */
1560 47672875 : if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1561 47671753 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1562 : {
1563 8854 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1564 : {
1565 4427 : reg_state[i].use_index = -1;
1566 4427 : reg_state[i].store_ruid = reload_combine_ruid;
1567 4427 : reg_state[i].real_store_ruid = reload_combine_ruid;
1568 : }
1569 : }
1570 : else
1571 : {
1572 95960087 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1573 : {
1574 48291639 : reg_state[i].store_ruid = reload_combine_ruid;
1575 48291639 : if (GET_CODE (set) == SET)
1576 40441076 : reg_state[i].real_store_ruid = reload_combine_ruid;
1577 48291639 : reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
1578 : }
1579 : }
1580 : }
1581 :
1582 : /* XP points to a piece of rtl that has to be checked for any uses of
1583 : registers.
1584 : *XP is the pattern of INSN, or a part of it.
1585 : Called from reload_combine, and recursively by itself. */
1586 : static void
1587 218140937 : reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1588 : {
1589 257947307 : rtx x = *xp;
1590 257947307 : enum rtx_code code = x->code;
1591 257947307 : const char *fmt;
1592 257947307 : int i, j;
1593 257947307 : rtx offset = const0_rtx; /* For the REG case below. */
1594 :
1595 257947307 : switch (code)
1596 : {
1597 58135663 : case SET:
1598 58135663 : if (REG_P (SET_DEST (x)))
1599 : {
1600 39806370 : reload_combine_note_use (&SET_SRC (x), insn, ruid, NULL_RTX);
1601 39806370 : return;
1602 : }
1603 : break;
1604 :
1605 653906 : case USE:
1606 : /* If this is the USE of a return value, we can't change it. */
1607 653906 : if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
1608 : {
1609 : /* Mark the return register as used in an unknown fashion. */
1610 559821 : rtx reg = XEXP (x, 0);
1611 559821 : unsigned int end_regno = END_REGNO (reg);
1612 1148125 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1613 588304 : reg_state[regno].use_index = -1;
1614 : return;
1615 : }
1616 : break;
1617 :
1618 7477929 : case CLOBBER:
1619 7477929 : if (REG_P (SET_DEST (x)))
1620 : {
1621 : /* No spurious CLOBBERs of pseudo registers may remain. */
1622 7426186 : gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1623 : return;
1624 : }
1625 : break;
1626 :
1627 23433096 : case PLUS:
1628 : /* We are interested in (plus (reg) (const_int)) . */
1629 23433096 : if (!REG_P (XEXP (x, 0))
1630 21023046 : || !CONST_INT_P (XEXP (x, 1)))
1631 : break;
1632 : offset = XEXP (x, 1);
1633 : x = XEXP (x, 0);
1634 : /* Fall through. */
1635 60281470 : case REG:
1636 60281470 : {
1637 60281470 : int regno = REGNO (x);
1638 60281470 : int use_index;
1639 60281470 : int nregs;
1640 :
1641 : /* No spurious USEs of pseudo registers may remain. */
1642 60281470 : gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1643 :
1644 60281470 : nregs = REG_NREGS (x);
1645 :
1646 : /* We can't substitute into multi-hard-reg uses. */
1647 60281470 : if (nregs > 1)
1648 : {
1649 1222053 : while (--nregs >= 0)
1650 814702 : reg_state[regno + nregs].use_index = -1;
1651 : return;
1652 : }
1653 :
1654 : /* We may be called to update uses in previously seen insns.
1655 : Don't add uses beyond the last store we saw. */
1656 59874119 : if (ruid < reg_state[regno].store_ruid)
1657 : return;
1658 :
1659 : /* If this register is already used in some unknown fashion, we
1660 : can't do anything.
1661 : If we decrement the index from zero to -1, we can't store more
1662 : uses, so this register becomes used in an unknown fashion. */
1663 59872971 : use_index = --reg_state[regno].use_index;
1664 59872971 : if (use_index < 0)
1665 : return;
1666 :
1667 36167233 : if (use_index == RELOAD_COMBINE_MAX_USES - 1)
1668 : {
1669 : /* This is the first use of this register we have seen since we
1670 : marked it as dead. */
1671 27356275 : reg_state[regno].offset = offset;
1672 27356275 : reg_state[regno].all_offsets_match = true;
1673 27356275 : reg_state[regno].use_ruid = ruid;
1674 : }
1675 : else
1676 : {
1677 8810958 : if (reg_state[regno].use_ruid > ruid)
1678 612 : reg_state[regno].use_ruid = ruid;
1679 :
1680 8810958 : if (! rtx_equal_p (offset, reg_state[regno].offset))
1681 3998189 : reg_state[regno].all_offsets_match = false;
1682 : }
1683 :
1684 36167233 : reg_state[regno].reg_use[use_index].insn = insn;
1685 36167233 : reg_state[regno].reg_use[use_index].ruid = ruid;
1686 36167233 : reg_state[regno].reg_use[use_index].containing_mem = containing_mem;
1687 36167233 : reg_state[regno].reg_use[use_index].usep = xp;
1688 36167233 : return;
1689 : }
1690 :
1691 : case MEM:
1692 149873460 : containing_mem = x;
1693 : break;
1694 :
1695 : default:
1696 : break;
1697 : }
1698 :
1699 : /* Recursively process the components of X. */
1700 149873460 : fmt = GET_RTX_FORMAT (code);
1701 383198277 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1702 : {
1703 233324817 : if (fmt[i] == 'e')
1704 136545480 : reload_combine_note_use (&XEXP (x, i), insn, ruid, containing_mem);
1705 96779337 : else if (fmt[i] == 'E')
1706 : {
1707 30011714 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1708 20206659 : reload_combine_note_use (&XVECEXP (x, i, j), insn, ruid,
1709 : containing_mem);
1710 : }
1711 : }
1712 : }
1713 :
1714 : /* See if we can reduce the cost of a constant by replacing a move
1715 : with an add. We track situations in which a register is set to a
1716 : constant or to a register plus a constant. */
1717 : /* We cannot do our optimization across labels. Invalidating all the
1718 : information about register contents we have would be costly, so we
1719 : use move2add_last_label_luid to note where the label is and then
1720 : later disable any optimization that would cross it.
1721 : reg_offset[n] / reg_base_reg[n] / reg_symbol_ref[n] / reg_mode[n]
1722 : are only valid if reg_set_luid[n] is greater than
1723 : move2add_last_label_luid.
1724 : For a set that established a new (potential) base register with
1725 : non-constant value, we use move2add_luid from the place where the
1726 : setting insn is encountered; registers based off that base then
1727 : get the same reg_set_luid. Constants all get
1728 : move2add_last_label_luid + 1 as their reg_set_luid. */
1729 : static int reg_set_luid[FIRST_PSEUDO_REGISTER];
1730 :
1731 : /* If reg_base_reg[n] is negative, register n has been set to
1732 : reg_offset[n] or reg_symbol_ref[n] + reg_offset[n] in mode reg_mode[n].
1733 : If reg_base_reg[n] is non-negative, register n has been set to the
1734 : sum of reg_offset[n] and the value of register reg_base_reg[n]
1735 : before reg_set_luid[n], calculated in mode reg_mode[n] .
1736 : For multi-hard-register registers, all but the first one are
1737 : recorded as BLKmode in reg_mode. Setting reg_mode to VOIDmode
1738 : marks it as invalid. */
1739 : static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
1740 : static int reg_base_reg[FIRST_PSEUDO_REGISTER];
1741 : static rtx reg_symbol_ref[FIRST_PSEUDO_REGISTER];
1742 : static machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
1743 :
1744 : /* move2add_luid is linearly increased while scanning the instructions
1745 : from first to last. It is used to set reg_set_luid in
1746 : reload_cse_move2add and move2add_note_store. */
1747 : static int move2add_luid;
1748 :
1749 : /* move2add_last_label_luid is set whenever a label is found. Labels
1750 : invalidate all previously collected reg_offset data. */
1751 : static int move2add_last_label_luid;
1752 :
1753 : /* ??? We don't know how zero / sign extension is handled, hence we
1754 : can't go from a narrower to a wider mode. */
1755 : #define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
1756 : (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
1757 : || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
1758 : && TRULY_NOOP_TRUNCATION_MODES_P (OUTMODE, INMODE)))
1759 :
1760 : /* Record that REG is being set to a value with the mode of REG. */
1761 :
1762 : static void
1763 52645715 : move2add_record_mode (rtx reg)
1764 : {
1765 52645715 : int regno, nregs;
1766 52645715 : machine_mode mode = GET_MODE (reg);
1767 :
1768 52645715 : if (GET_CODE (reg) == SUBREG)
1769 : {
1770 3652 : regno = subreg_regno (reg);
1771 3652 : nregs = subreg_nregs (reg);
1772 : }
1773 52642063 : else if (REG_P (reg))
1774 : {
1775 52642063 : regno = REGNO (reg);
1776 52642063 : nregs = REG_NREGS (reg);
1777 : }
1778 : else
1779 0 : gcc_unreachable ();
1780 53298684 : for (int i = nregs - 1; i > 0; i--)
1781 652969 : reg_mode[regno + i] = BLKmode;
1782 52645715 : reg_mode[regno] = mode;
1783 52645715 : }
1784 :
1785 : /* Record that REG is being set to the sum of SYM and OFF. */
1786 :
1787 : static void
1788 2087787 : move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1789 : {
1790 2087787 : int regno = REGNO (reg);
1791 :
1792 2087787 : move2add_record_mode (reg);
1793 2087787 : reg_set_luid[regno] = move2add_luid;
1794 2087787 : reg_base_reg[regno] = -1;
1795 2087787 : reg_symbol_ref[regno] = sym;
1796 2087787 : reg_offset[regno] = INTVAL (off);
1797 2087787 : }
1798 :
1799 : /* Check if REGNO contains a valid value in MODE. */
1800 :
1801 : static bool
1802 209989416 : move2add_valid_value_p (int regno, scalar_int_mode mode)
1803 : {
1804 209989416 : if (reg_set_luid[regno] <= move2add_last_label_luid)
1805 : return false;
1806 :
1807 21344367 : if (mode != reg_mode[regno])
1808 : {
1809 11404014 : scalar_int_mode old_mode;
1810 11404014 : if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1811 7260020 : || !MODES_OK_FOR_MOVE2ADD (mode, old_mode)
1812 523031 : || !REG_CAN_CHANGE_MODE_P (regno, old_mode, mode))
1813 10880983 : return false;
1814 : /* The value loaded into regno in reg_mode[regno] is also valid in
1815 : mode after truncation only if (REG:mode regno) is the lowpart of
1816 : (REG:reg_mode[regno] regno). Now, for big endian, the starting
1817 : regno of the lowpart might be different. */
1818 523031 : poly_int64 s_off = subreg_lowpart_offset (mode, old_mode);
1819 523031 : s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1820 523031 : if (maybe_ne (s_off, 0))
1821 : /* We could in principle adjust regno, check reg_mode[regno] to be
1822 : BLKmode, and return s_off to the caller (vs. -1 for failure),
1823 : but we currently have no callers that could make use of this
1824 : information. */
1825 : return false;
1826 : }
1827 :
1828 10514057 : for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1829 54677 : if (reg_mode[i] != BLKmode)
1830 : return false;
1831 : return true;
1832 : }
1833 :
1834 : /* This function is called with INSN that sets REG (of mode MODE)
1835 : to (SYM + OFF), while REG is known to already have value (SYM + offset).
1836 : This function tries to change INSN into an add instruction
1837 : (set (REG) (plus (REG) (OFF - offset))) using the known value.
1838 : It also updates the information about REG's known value.
1839 : Return true if we made a change. */
1840 :
1841 : static bool
1842 151753 : move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1843 : rtx_insn *insn)
1844 : {
1845 151753 : rtx set = single_set (insn);
1846 151753 : rtx src = SET_SRC (set);
1847 151753 : int regno = REGNO (reg);
1848 151753 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1849 151753 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1850 151753 : bool changed = false;
1851 :
1852 : /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1853 : use (set (reg) (reg)) instead.
1854 : We don't delete this insn, nor do we convert it into a
1855 : note, to avoid losing register notes or the return
1856 : value flag. jump2 already knows how to get rid of
1857 : no-op moves. */
1858 151753 : if (new_src == const0_rtx)
1859 : {
1860 : /* If the constants are different, this is a
1861 : truncation, that, if turned into (set (reg)
1862 : (reg)), would be discarded. Maybe we should
1863 : try a truncMN pattern? */
1864 25616 : if (INTVAL (off) == reg_offset [regno])
1865 23468 : changed = validate_change (insn, &SET_SRC (set), reg, 0);
1866 : }
1867 : else
1868 : {
1869 126137 : struct full_rtx_costs oldcst, newcst;
1870 126137 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1871 :
1872 126137 : get_full_set_rtx_cost (set, &oldcst);
1873 126137 : SET_SRC (set) = tem;
1874 126137 : get_full_set_rtx_cost (set, &newcst);
1875 126137 : SET_SRC (set) = src;
1876 :
1877 126137 : if (costs_lt_p (&newcst, &oldcst, speed)
1878 126137 : && have_add2_insn (reg, new_src))
1879 3661 : changed = validate_change (insn, &SET_SRC (set), tem, 0);
1880 122476 : else if (sym == NULL_RTX && mode != BImode)
1881 : {
1882 121041 : scalar_int_mode narrow_mode;
1883 405452 : FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1884 : {
1885 284411 : if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1886 284411 : && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1887 212066 : == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1888 : {
1889 93659 : rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1890 93659 : rtx narrow_src = gen_int_mode (INTVAL (off),
1891 : narrow_mode);
1892 93659 : rtx new_set
1893 93659 : = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1894 : narrow_reg),
1895 : narrow_src);
1896 93659 : get_full_set_rtx_cost (new_set, &newcst);
1897 :
1898 : /* We perform this replacement only if NEXT is either a
1899 : naked SET, or else its single_set is the first element
1900 : in a PARALLEL. */
1901 93659 : rtx *setloc = GET_CODE (PATTERN (insn)) == PARALLEL
1902 93659 : ? &XVECEXP (PATTERN (insn), 0, 0) : &PATTERN (insn);
1903 93659 : if (*setloc == set && costs_lt_p (&newcst, &oldcst, speed))
1904 : {
1905 0 : changed = validate_change (insn, setloc, new_set, 0);
1906 0 : if (changed)
1907 : break;
1908 : }
1909 : }
1910 : }
1911 : }
1912 : }
1913 151753 : move2add_record_sym_value (reg, sym, off);
1914 151753 : return changed;
1915 : }
1916 :
1917 :
1918 : /* This function is called with INSN that sets REG (of mode MODE) to
1919 : (SYM + OFF), but REG doesn't have known value (SYM + offset). This
1920 : function tries to find another register which is known to already have
1921 : value (SYM + offset) and change INSN into an add instruction
1922 : (set (REG) (plus (the found register) (OFF - offset))) if such
1923 : a register is found. It also updates the information about
1924 : REG's known value.
1925 : Return true iff we made a change. */
1926 :
1927 : static bool
1928 1855335 : move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1929 : rtx_insn *insn)
1930 : {
1931 1855335 : rtx set = single_set (insn);
1932 1855335 : rtx src = SET_SRC (set);
1933 1855335 : int regno = REGNO (reg);
1934 1855335 : int min_regno = 0;
1935 1855335 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1936 1855335 : int i;
1937 1855335 : bool changed = false;
1938 1855335 : struct full_rtx_costs oldcst, newcst, mincst;
1939 1855335 : rtx plus_expr;
1940 :
1941 1855335 : init_costs_to_max (&mincst);
1942 1855335 : get_full_set_rtx_cost (set, &oldcst);
1943 :
1944 1855335 : plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1945 1855335 : SET_SRC (set) = plus_expr;
1946 :
1947 172545736 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1948 170690407 : if (move2add_valid_value_p (i, mode)
1949 3682882 : && reg_base_reg[i] < 0
1950 1455367 : && reg_symbol_ref[i] != NULL_RTX
1951 171679632 : && rtx_equal_p (sym, reg_symbol_ref[i]))
1952 : {
1953 36994 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1954 18497 : GET_MODE (reg));
1955 : /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1956 : use (set (reg) (reg)) instead.
1957 : We don't delete this insn, nor do we convert it into a
1958 : note, to avoid losing register notes or the return
1959 : value flag. jump2 already knows how to get rid of
1960 : no-op moves. */
1961 18497 : if (new_src == const0_rtx)
1962 : {
1963 6 : init_costs_to_zero (&mincst);
1964 6 : min_regno = i;
1965 6 : break;
1966 : }
1967 : else
1968 : {
1969 18491 : XEXP (plus_expr, 1) = new_src;
1970 18491 : get_full_set_rtx_cost (set, &newcst);
1971 :
1972 18491 : if (costs_lt_p (&newcst, &mincst, speed))
1973 : {
1974 17952 : mincst = newcst;
1975 17952 : min_regno = i;
1976 : }
1977 : }
1978 : }
1979 1855335 : SET_SRC (set) = src;
1980 :
1981 1855335 : if (costs_lt_p (&mincst, &oldcst, speed))
1982 : {
1983 44 : rtx tem;
1984 :
1985 44 : tem = gen_rtx_REG (GET_MODE (reg), min_regno);
1986 44 : if (i != min_regno)
1987 : {
1988 76 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[min_regno],
1989 38 : GET_MODE (reg));
1990 38 : tem = gen_rtx_PLUS (GET_MODE (reg), tem, new_src);
1991 : }
1992 44 : if (validate_change (insn, &SET_SRC (set), tem, 0))
1993 1855335 : changed = true;
1994 : }
1995 1855335 : reg_set_luid[regno] = move2add_luid;
1996 1855335 : move2add_record_sym_value (reg, sym, off);
1997 1855335 : return changed;
1998 : }
1999 :
2000 : /* Perform any invalidations necessary for INSN. */
2001 :
2002 : static void
2003 103005976 : reload_cse_move2add_invalidate (rtx_insn *insn)
2004 : {
2005 125508236 : for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
2006 : {
2007 22502260 : if (REG_NOTE_KIND (note) == REG_INC
2008 0 : && REG_P (XEXP (note, 0)))
2009 : {
2010 : /* Reset the information about this register. */
2011 0 : int regno = REGNO (XEXP (note, 0));
2012 0 : if (regno < FIRST_PSEUDO_REGISTER)
2013 : {
2014 0 : move2add_record_mode (XEXP (note, 0));
2015 0 : reg_mode[regno] = VOIDmode;
2016 : }
2017 : }
2018 : }
2019 :
2020 : /* There are no REG_INC notes for SP autoinc. */
2021 103005976 : subrtx_var_iterator::array_type array;
2022 528732920 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
2023 : {
2024 425726944 : rtx mem = *iter;
2025 425726944 : if (mem
2026 425726944 : && MEM_P (mem)
2027 27567068 : && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
2028 : {
2029 1674723 : if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
2030 1674723 : reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
2031 : }
2032 : }
2033 :
2034 103005976 : note_stores (insn, move2add_note_store, insn);
2035 :
2036 : /* If INSN is a conditional branch, we try to extract an
2037 : implicit set out of it. */
2038 103005976 : if (any_condjump_p (insn))
2039 : {
2040 4754657 : rtx cnd = fis_get_condition (insn);
2041 :
2042 4754657 : if (cnd != NULL_RTX
2043 4250914 : && GET_CODE (cnd) == NE
2044 1906244 : && REG_P (XEXP (cnd, 0))
2045 1263875 : && !reg_set_p (XEXP (cnd, 0), insn)
2046 : /* The following two checks, which are also in
2047 : move2add_note_store, are intended to reduce the
2048 : number of calls to gen_rtx_SET to avoid memory
2049 : allocation if possible. */
2050 1263875 : && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2051 1263874 : && REG_NREGS (XEXP (cnd, 0)) == 1
2052 6018531 : && CONST_INT_P (XEXP (cnd, 1)))
2053 : {
2054 851257 : rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2055 851257 : move2add_note_store (SET_DEST (implicit_set), implicit_set, insn);
2056 : }
2057 : }
2058 :
2059 : /* If this is a CALL_INSN, all call used registers are stored with
2060 : unknown values. */
2061 103005976 : if (CALL_P (insn))
2062 : {
2063 4605097 : function_abi callee_abi = insn_callee_abi (insn);
2064 428274021 : for (int i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2065 423668924 : if (reg_mode[i] != VOIDmode
2066 21370470 : && reg_mode[i] != BLKmode
2067 444489896 : && callee_abi.clobbers_reg_p (reg_mode[i], i))
2068 : /* Reset the information about this register. */
2069 7907439 : reg_mode[i] = VOIDmode;
2070 : }
2071 103005976 : }
2072 :
2073 : /* Convert move insns with constant inputs to additions if they are cheaper.
2074 : Return true if any changes were made. */
2075 : static bool
2076 1041770 : reload_cse_move2add (rtx_insn *first)
2077 : {
2078 1041770 : int i;
2079 1041770 : rtx_insn *insn;
2080 1041770 : bool changed = false;
2081 :
2082 96884610 : for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2083 : {
2084 95842840 : reg_set_luid[i] = 0;
2085 95842840 : reg_offset[i] = 0;
2086 95842840 : reg_base_reg[i] = 0;
2087 95842840 : reg_symbol_ref[i] = NULL_RTX;
2088 95842840 : reg_mode[i] = VOIDmode;
2089 : }
2090 :
2091 1041770 : move2add_last_label_luid = 0;
2092 1041770 : move2add_luid = 2;
2093 133652922 : for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
2094 : {
2095 132611152 : rtx set;
2096 :
2097 132611152 : if (LABEL_P (insn))
2098 : {
2099 5040173 : move2add_last_label_luid = move2add_luid;
2100 : /* We're going to increment move2add_luid twice after a
2101 : label, so that we can use move2add_last_label_luid + 1 as
2102 : the luid for constants. */
2103 5040173 : move2add_luid++;
2104 137651325 : continue;
2105 : }
2106 127570979 : if (! INSN_P (insn))
2107 22557915 : continue;
2108 105013064 : set = single_set (insn);
2109 : /* For simplicity, we only perform this optimization on
2110 : single-sets. */
2111 105013064 : scalar_int_mode mode;
2112 105013064 : if (set
2113 53651991 : && REG_P (SET_DEST (set))
2114 141583267 : && is_a <scalar_int_mode> (GET_MODE (SET_DEST (set)), &mode))
2115 : {
2116 27065397 : rtx reg = SET_DEST (set);
2117 27065397 : int regno = REGNO (reg);
2118 27065397 : rtx src = SET_SRC (set);
2119 :
2120 : /* Check if we have valid information on the contents of this
2121 : register in the mode of REG. */
2122 27065397 : if (move2add_valid_value_p (regno, mode)
2123 27065397 : && dbg_cnt (cse2_move2add))
2124 : {
2125 : /* Try to transform (set (REGX) (CONST_INT A))
2126 : ...
2127 : (set (REGX) (CONST_INT B))
2128 : to
2129 : (set (REGX) (CONST_INT A))
2130 : ...
2131 : (set (REGX) (plus (REGX) (CONST_INT B-A)))
2132 : or
2133 : (set (REGX) (CONST_INT A))
2134 : ...
2135 : (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
2136 : */
2137 :
2138 3816458 : if (CONST_INT_P (src)
2139 327213 : && reg_base_reg[regno] < 0
2140 152478 : && reg_symbol_ref[regno] == NULL_RTX)
2141 : {
2142 150006 : changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
2143 : src, insn);
2144 150006 : continue;
2145 : }
2146 :
2147 : /* Try to transform (set (REGX) (REGY))
2148 : (set (REGX) (PLUS (REGX) (CONST_INT A)))
2149 : ...
2150 : (set (REGX) (REGY))
2151 : (set (REGX) (PLUS (REGX) (CONST_INT B)))
2152 : to
2153 : (set (REGX) (REGY))
2154 : (set (REGX) (PLUS (REGX) (CONST_INT A)))
2155 : ...
2156 : (set (REGX) (plus (REGX) (CONST_INT B-A))) */
2157 3666452 : else if (REG_P (src)
2158 452330 : && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
2159 117727 : && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
2160 3784179 : && move2add_valid_value_p (REGNO (src), mode))
2161 : {
2162 91486 : rtx_insn *next = next_nonnote_nondebug_insn (insn);
2163 91486 : rtx set = NULL_RTX;
2164 91486 : if (next)
2165 91475 : set = single_set (next);
2166 91475 : if (set
2167 70848 : && SET_DEST (set) == reg
2168 7063 : && GET_CODE (SET_SRC (set)) == PLUS
2169 663 : && XEXP (SET_SRC (set), 0) == reg
2170 658 : && CONST_INT_P (XEXP (SET_SRC (set), 1)))
2171 : {
2172 406 : rtx src3 = XEXP (SET_SRC (set), 1);
2173 406 : unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
2174 406 : HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
2175 406 : HOST_WIDE_INT regno_offset = reg_offset[regno];
2176 406 : rtx new_src =
2177 812 : gen_int_mode (added_offset
2178 406 : + base_offset
2179 406 : - regno_offset,
2180 : mode);
2181 406 : bool success = false;
2182 406 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
2183 :
2184 406 : if (new_src == const0_rtx)
2185 : /* See above why we create (set (reg) (reg)) here. */
2186 37 : success
2187 37 : = validate_change (next, &SET_SRC (set), reg, 0);
2188 : else
2189 : {
2190 369 : rtx old_src = SET_SRC (set);
2191 369 : struct full_rtx_costs oldcst, newcst;
2192 369 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
2193 :
2194 369 : get_full_set_rtx_cost (set, &oldcst);
2195 369 : SET_SRC (set) = tem;
2196 369 : get_full_set_src_cost (tem, mode, &newcst);
2197 369 : SET_SRC (set) = old_src;
2198 369 : costs_add_n_insns (&oldcst, 1);
2199 :
2200 369 : rtx *setloc = GET_CODE (PATTERN (next)) == PARALLEL
2201 369 : ? &XVECEXP (PATTERN (next), 0, 0) : &PATTERN (next);
2202 369 : if (*setloc == set
2203 369 : && costs_lt_p (&newcst, &oldcst, speed)
2204 738 : && have_add2_insn (reg, new_src))
2205 : {
2206 369 : rtx newpat = gen_rtx_SET (reg, tem);
2207 369 : success
2208 369 : = validate_change (next, setloc, newpat, 0);
2209 : }
2210 : }
2211 406 : if (success)
2212 406 : delete_insn (insn);
2213 406 : changed |= success;
2214 406 : insn = next;
2215 : /* Make sure to perform any invalidations related to
2216 : NEXT/INSN since we're going to bypass the normal
2217 : flow with the continue below.
2218 :
2219 : Do this before recording the new mode/offset. */
2220 406 : reload_cse_move2add_invalidate (insn);
2221 406 : move2add_record_mode (reg);
2222 406 : reg_offset[regno]
2223 406 : = trunc_int_for_mode (added_offset + base_offset,
2224 : mode);
2225 406 : continue;
2226 406 : }
2227 : }
2228 : }
2229 :
2230 : /* Try to transform
2231 : (set (REGX) (CONST (PLUS (SYMBOL_REF) (CONST_INT A))))
2232 : ...
2233 : (set (REGY) (CONST (PLUS (SYMBOL_REF) (CONST_INT B))))
2234 : to
2235 : (set (REGX) (CONST (PLUS (SYMBOL_REF) (CONST_INT A))))
2236 : ...
2237 : (set (REGY) (CONST (PLUS (REGX) (CONST_INT B-A)))) */
2238 26914985 : if ((GET_CODE (src) == SYMBOL_REF
2239 25117667 : || (GET_CODE (src) == CONST
2240 60005 : && GET_CODE (XEXP (src, 0)) == PLUS
2241 59784 : && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF
2242 59764 : && CONST_INT_P (XEXP (XEXP (src, 0), 1))))
2243 26974749 : && dbg_cnt (cse2_move2add))
2244 : {
2245 1857082 : rtx sym, off;
2246 :
2247 1857082 : if (GET_CODE (src) == SYMBOL_REF)
2248 : {
2249 1797318 : sym = src;
2250 1797318 : off = const0_rtx;
2251 : }
2252 : else
2253 : {
2254 59764 : sym = XEXP (XEXP (src, 0), 0);
2255 59764 : off = XEXP (XEXP (src, 0), 1);
2256 : }
2257 :
2258 : /* If the reg already contains the value which is sum of
2259 : sym and some constant value, we can use an add2 insn. */
2260 1857082 : if (move2add_valid_value_p (regno, mode)
2261 193350 : && reg_base_reg[regno] < 0
2262 127172 : && reg_symbol_ref[regno] != NULL_RTX
2263 1908747 : && rtx_equal_p (sym, reg_symbol_ref[regno]))
2264 1747 : changed |= move2add_use_add2_insn (mode, reg, sym, off, insn);
2265 :
2266 : /* Otherwise, we have to find a register whose value is sum
2267 : of sym and some constant value. */
2268 : else
2269 1855335 : changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2270 :
2271 1857082 : continue;
2272 1857082 : }
2273 : }
2274 103005570 : reload_cse_move2add_invalidate (insn);
2275 : }
2276 1041770 : return changed;
2277 : }
2278 :
2279 : /* SET is a SET or CLOBBER that sets DST. DATA is the insn which
2280 : contains SET.
2281 : Update reg_set_luid, reg_offset and reg_base_reg accordingly.
2282 : Called from reload_cse_move2add via note_stores. */
2283 :
2284 : static void
2285 60886269 : move2add_note_store (rtx dst, const_rtx set, void *data)
2286 : {
2287 60886269 : rtx_insn *insn = (rtx_insn *) data;
2288 60886269 : unsigned int regno = 0;
2289 60886269 : scalar_int_mode mode;
2290 :
2291 60886269 : if (GET_CODE (dst) == SUBREG)
2292 3652 : regno = subreg_regno (dst);
2293 60882617 : else if (REG_P (dst))
2294 43699741 : regno = REGNO (dst);
2295 : else
2296 60886269 : return;
2297 :
2298 43703393 : if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2299 16655403 : goto invalidate;
2300 :
2301 27047990 : if (GET_CODE (set) == SET)
2302 : {
2303 26496609 : rtx note, sym = NULL_RTX;
2304 26496609 : rtx off;
2305 :
2306 26496609 : note = find_reg_equal_equiv_note (insn);
2307 26496609 : if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2308 : {
2309 70430 : sym = XEXP (note, 0);
2310 70430 : off = const0_rtx;
2311 : }
2312 4162993 : else if (note && GET_CODE (XEXP (note, 0)) == CONST
2313 10494 : && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2314 10289 : && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2315 10269 : && CONST_INT_P (XEXP (XEXP (XEXP (note, 0), 0), 1)))
2316 : {
2317 : sym = XEXP (XEXP (XEXP (note, 0), 0), 0);
2318 : off = XEXP (XEXP (XEXP (note, 0), 0), 1);
2319 : }
2320 :
2321 80699 : if (sym != NULL_RTX)
2322 : {
2323 80699 : move2add_record_sym_value (dst, sym, off);
2324 80699 : return;
2325 : }
2326 : }
2327 :
2328 26967291 : if (GET_CODE (set) == SET
2329 26415910 : && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2330 26414870 : && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2331 : {
2332 26411765 : rtx src = SET_SRC (set);
2333 26411765 : rtx base_reg;
2334 26411765 : unsigned HOST_WIDE_INT offset;
2335 26411765 : int base_regno;
2336 :
2337 26411765 : switch (GET_CODE (src))
2338 : {
2339 5960845 : case PLUS:
2340 5960845 : if (REG_P (XEXP (src, 0)))
2341 : {
2342 5661377 : base_reg = XEXP (src, 0);
2343 :
2344 5661377 : if (CONST_INT_P (XEXP (src, 1)))
2345 4876916 : offset = UINTVAL (XEXP (src, 1));
2346 784461 : else if (REG_P (XEXP (src, 1))
2347 784461 : && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2348 : {
2349 88705 : if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2350 88705 : && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2351 6923 : offset = reg_offset[REGNO (XEXP (src, 1))];
2352 : /* Maybe the first register is known to be a
2353 : constant. */
2354 81782 : else if (move2add_valid_value_p (REGNO (base_reg), mode)
2355 22843 : && reg_base_reg[REGNO (base_reg)] < 0
2356 82670 : && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2357 : {
2358 781 : offset = reg_offset[REGNO (base_reg)];
2359 781 : base_reg = XEXP (src, 1);
2360 : }
2361 : else
2362 81001 : goto invalidate;
2363 : }
2364 : else
2365 695756 : goto invalidate;
2366 :
2367 : break;
2368 : }
2369 :
2370 299468 : goto invalidate;
2371 :
2372 : case REG:
2373 : base_reg = src;
2374 : offset = 0;
2375 : break;
2376 :
2377 4305898 : case CONST_INT:
2378 : /* Start tracking the register as a constant. */
2379 4305898 : reg_base_reg[regno] = -1;
2380 4305898 : reg_symbol_ref[regno] = NULL_RTX;
2381 4305898 : reg_offset[regno] = INTVAL (SET_SRC (set));
2382 : /* We assign the same luid to all registers set to constants. */
2383 4305898 : reg_set_luid[regno] = move2add_last_label_luid + 1;
2384 4305898 : move2add_record_mode (dst);
2385 4305898 : return;
2386 :
2387 11531158 : default:
2388 11531158 : goto invalidate;
2389 : }
2390 :
2391 9498484 : base_regno = REGNO (base_reg);
2392 : /* If information about the base register is not valid, set it
2393 : up as a new base register, pretending its value is known
2394 : starting from the current insn. */
2395 9498484 : if (!move2add_valid_value_p (base_regno, mode))
2396 : {
2397 6934828 : reg_base_reg[base_regno] = base_regno;
2398 6934828 : reg_symbol_ref[base_regno] = NULL_RTX;
2399 6934828 : reg_offset[base_regno] = 0;
2400 6934828 : reg_set_luid[base_regno] = move2add_luid;
2401 6934828 : gcc_assert (GET_MODE (base_reg) == mode);
2402 6934828 : move2add_record_mode (base_reg);
2403 : }
2404 :
2405 : /* Copy base information from our base register. */
2406 9498484 : reg_set_luid[regno] = reg_set_luid[base_regno];
2407 9498484 : reg_base_reg[regno] = reg_base_reg[base_regno];
2408 9498484 : reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2409 :
2410 : /* Compute the sum of the offsets or constants. */
2411 9498484 : reg_offset[regno]
2412 9498484 : = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2413 :
2414 9498484 : move2add_record_mode (dst);
2415 9498484 : }
2416 : else
2417 : {
2418 555526 : invalidate:
2419 : /* Invalidate the contents of the register. */
2420 29818312 : move2add_record_mode (dst);
2421 29818312 : reg_mode[regno] = VOIDmode;
2422 : }
2423 : }
2424 :
2425 : namespace {
2426 :
2427 : const pass_data pass_data_postreload_cse =
2428 : {
2429 : RTL_PASS, /* type */
2430 : "postreload", /* name */
2431 : OPTGROUP_NONE, /* optinfo_flags */
2432 : TV_RELOAD_CSE_REGS, /* tv_id */
2433 : 0, /* properties_required */
2434 : 0, /* properties_provided */
2435 : 0, /* properties_destroyed */
2436 : 0, /* todo_flags_start */
2437 : TODO_df_finish, /* todo_flags_finish */
2438 : };
2439 :
2440 : class pass_postreload_cse : public rtl_opt_pass
2441 : {
2442 : public:
2443 298828 : pass_postreload_cse (gcc::context *ctxt)
2444 597656 : : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2445 : {}
2446 :
2447 : /* opt_pass methods: */
2448 1488378 : bool gate (function *) final override
2449 : {
2450 1488378 : return (optimize > 0 && reload_completed);
2451 : }
2452 :
2453 : unsigned int execute (function *) final override;
2454 :
2455 : }; // class pass_postreload_cse
2456 :
2457 : unsigned int
2458 1041770 : pass_postreload_cse::execute (function *fun)
2459 : {
2460 1041770 : if (!dbg_cnt (postreload_cse))
2461 : return 0;
2462 :
2463 : /* Do a very simple CSE pass over just the hard registers. */
2464 1041770 : reload_cse_regs (get_insns ());
2465 : /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2466 : Remove any EH edges associated with them. */
2467 1041770 : if (fun->can_throw_non_call_exceptions
2468 1041770 : && purge_all_dead_edges ())
2469 116 : cleanup_cfg (0);
2470 :
2471 : return 0;
2472 : }
2473 :
2474 : } // anon namespace
2475 :
2476 : rtl_opt_pass *
2477 298828 : make_pass_postreload_cse (gcc::context *ctxt)
2478 : {
2479 298828 : return new pass_postreload_cse (ctxt);
2480 : }
|