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 1041492 : reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
64 : {
65 1041492 : bool moves_converted;
66 1041492 : reload_cse_regs_1 ();
67 1041492 : reload_combine ();
68 1041492 : moves_converted = reload_cse_move2add (first);
69 1041492 : if (flag_expensive_optimizations)
70 : {
71 961508 : if (moves_converted)
72 8976 : reload_combine ();
73 961508 : reload_cse_regs_1 ();
74 : }
75 1041492 : }
76 :
77 : /* Try to simplify INSN. Return true if the CFG may have changed. */
78 : static bool
79 208369941 : reload_cse_simplify (rtx_insn *insn, rtx testreg)
80 : {
81 208369941 : rtx body = PATTERN (insn);
82 208369941 : basic_block insn_bb = BLOCK_FOR_INSN (insn);
83 208369941 : 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 208369941 : if (NO_FUNCTION_CSE && CALL_P (insn))
88 : return false;
89 :
90 : /* Remember if this insn has been sp += const_int. */
91 199408665 : rtx sp_set = set_for_reg_notes (insn);
92 199408665 : rtx sp_addend = NULL_RTX;
93 199408665 : if (sp_set
94 67537082 : && SET_DEST (sp_set) == stack_pointer_rtx
95 3328408 : && GET_CODE (SET_SRC (sp_set)) == PLUS
96 3297744 : && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
97 3297641 : && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
98 199408665 : sp_addend = XEXP (SET_SRC (sp_set), 1);
99 :
100 199408665 : if (GET_CODE (body) == SET)
101 : {
102 87712351 : 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 87712351 : count += reload_cse_simplify_set (body, insn);
110 :
111 87712351 : if (!count && cselib_redundant_set_p (body))
112 : {
113 225734 : if (check_for_inc_dec (insn))
114 225734 : delete_insn_and_edges (insn);
115 : /* We're done with this insn. */
116 225734 : goto done;
117 : }
118 :
119 87486617 : if (count > 0)
120 148065 : apply_change_group ();
121 : else
122 87338552 : reload_cse_simplify_operands (insn, testreg);
123 : }
124 111696314 : else if (GET_CODE (body) == PARALLEL)
125 : {
126 13835746 : int i;
127 13835746 : int count = 0;
128 13835746 : 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 13835746 : if (asm_noperands (body) >= 0)
134 : {
135 615673 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
136 : {
137 469868 : rtx part = XVECEXP (body, 0, i);
138 469868 : if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
139 200634 : 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 27664514 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
146 : {
147 27660564 : rtx part = XVECEXP (body, 0, i);
148 27660564 : if (GET_CODE (part) == SET)
149 : {
150 13729901 : if (! cselib_redundant_set_p (part))
151 : break;
152 4017 : if (REG_P (SET_DEST (part))
153 4017 : && REG_FUNCTION_VALUE_P (SET_DEST (part)))
154 : {
155 0 : if (value)
156 : break;
157 : value = SET_DEST (part);
158 : }
159 : }
160 13930663 : else if (GET_CODE (part) != CLOBBER && GET_CODE (part) != USE)
161 : break;
162 : }
163 :
164 13835746 : if (i < 0)
165 : {
166 3950 : if (check_for_inc_dec (insn))
167 3950 : delete_insn_and_edges (insn);
168 : /* We're done with this insn. */
169 3950 : goto done;
170 : }
171 :
172 : /* It's not a no-op, but we can try to simplify it. */
173 42240282 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
174 28408486 : if (GET_CODE (XVECEXP (body, 0, i)) == SET)
175 14481699 : count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
176 :
177 13831796 : if (count > 0)
178 5429 : apply_change_group ();
179 : else
180 13826367 : 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 199178981 : if (sp_addend
186 3297641 : && SET_DEST (sp_set) == stack_pointer_rtx
187 3297641 : && REG_P (SET_SRC (sp_set)))
188 3035 : set_dst_reg_note (insn, REG_EQUAL,
189 3035 : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
190 : sp_addend), stack_pointer_rtx);
191 :
192 199175946 : done:
193 398814621 : 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 2003000 : reload_cse_regs_1 (void)
215 : {
216 2003000 : bool cfg_changed = false;
217 2003000 : basic_block bb;
218 2003000 : rtx_insn *insn;
219 2003000 : rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
220 :
221 2003000 : cselib_init (CSELIB_RECORD_MEMORY);
222 2003000 : init_alias_analysis ();
223 :
224 23174473 : 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 21171473 : rtx_insn *implicit_set;
230 :
231 21171473 : implicit_set = NULL;
232 21171473 : if (EDGE_COUNT (bb->preds) <= 3)
233 : {
234 20635179 : edge e;
235 20635179 : edge_iterator ei;
236 20635179 : rtx src = NULL_RTX;
237 20635179 : rtx dest = NULL_RTX;
238 :
239 : /* Iterate over each incoming edge and see if they
240 : all have the same implicit set. */
241 20635309 : FOR_EACH_EDGE (e, ei, bb->preds)
242 : {
243 : /* Skip the entry/exit block. */
244 20635179 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
245 : break;
246 :
247 : /* Verify this block ends with a suitable condjump */
248 18632232 : rtx_insn *condjump = BB_END (e->src);
249 18632232 : 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 14541230 : rtx pat = pc_set (condjump);
256 14541230 : rtx i_t_e = SET_SRC (pat);
257 14541230 : gcc_assert (GET_CODE (i_t_e) == IF_THEN_ELSE);
258 14541230 : rtx cond = XEXP (i_t_e, 0);
259 :
260 14541230 : if ((((e->flags & EDGE_FALLTHRU) != 0)
261 14541230 : == (XEXP (i_t_e, 1) == pc_rtx))
262 14541230 : ? GET_CODE (cond) == EQ
263 8980100 : : GET_CODE (cond) == NE)
264 : {
265 : /* If this is the first time through record
266 : the source and destination. */
267 5650191 : if (!dest)
268 : {
269 5650191 : dest = XEXP (cond, 0);
270 5650191 : 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 5650191 : if (!REG_P (dest)
286 5650167 : || !(REG_P (src) || CONST_INT_P (src))
287 5650167 : || GET_MODE_CLASS (GET_MODE (dest)) != MODE_INT
288 130 : || reg_set_p (dest, condjump)
289 5650321 : || 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 20635179 : if (dest && ei_end_p (ei))
303 130 : implicit_set = make_insn_raw (gen_rtx_SET (dest, src));
304 : }
305 :
306 273709713 : FOR_BB_INSNS (bb, insn)
307 : {
308 252538240 : 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 208369941 : if (implicit_set)
316 : {
317 130 : cselib_process_insn (implicit_set);
318 130 : implicit_set = NULL;
319 : }
320 208369941 : cfg_changed |= reload_cse_simplify (insn, testreg);
321 : }
322 :
323 252538240 : cselib_process_insn (insn);
324 : }
325 : }
326 :
327 : /* Clean up. */
328 2003000 : end_alias_analysis ();
329 2003000 : cselib_finish ();
330 2003000 : if (cfg_changed)
331 81 : cleanup_cfg (0);
332 2003000 : }
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 102194050 : reload_cse_simplify_set (rtx set, rtx_insn *insn)
342 : {
343 102194050 : int did_change = 0;
344 102194050 : int dreg;
345 102194050 : rtx src;
346 102194050 : reg_class_t dclass;
347 102194050 : int old_cost;
348 102194050 : cselib_val *val;
349 102194050 : struct elt_loc_list *l;
350 102194050 : enum rtx_code extend_op = UNKNOWN;
351 102194050 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
352 :
353 102194050 : dreg = true_regnum (SET_DEST (set));
354 102194050 : if (dreg < 0)
355 : return 0;
356 :
357 68748124 : src = SET_SRC (set);
358 68748124 : if (side_effects_p (src) || true_regnum (src) >= 0)
359 10818460 : return 0;
360 :
361 57929664 : 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 57929664 : 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 57929664 : val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
373 57929664 : if (! val)
374 : return 0;
375 :
376 : /* If memory loads are cheaper than register copies, don't change them. */
377 5611460 : if (MEM_P (src))
378 645465 : old_cost = memory_move_cost (GET_MODE (src), dclass, true);
379 4965995 : 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 4965995 : old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
384 :
385 11162370 : for (l = val->locs; l; l = l->next)
386 : {
387 5550910 : rtx this_rtx = l->loc;
388 5550910 : int this_cost;
389 :
390 5550910 : if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
391 : {
392 1870283 : 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 1870283 : this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
418 : }
419 3680627 : else if (REG_P (this_rtx))
420 : {
421 774193 : 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 774193 : this_cost = register_move_cost (GET_MODE (this_rtx),
428 774193 : REGNO_REG_CLASS (REGNO (this_rtx)),
429 : dclass);
430 : }
431 : else
432 2906434 : continue;
433 :
434 : /* If equal costs, prefer registers over anything else. That
435 : tends to lead to smaller instructions on some machines. */
436 2644476 : if (this_cost < old_cost
437 2491534 : || (this_cost == old_cost
438 1879749 : && REG_P (this_rtx)
439 15530 : && !REG_P (SET_SRC (set))))
440 : {
441 153817 : 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 153817 : validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
451 153817 : 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 101164919 : reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
471 : {
472 101164919 : int i, j;
473 :
474 : /* For each operand, all registers that are equivalent to it. */
475 101164919 : HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
476 :
477 101164919 : const char *constraints[MAX_RECOG_OPERANDS];
478 :
479 : /* Vector recording how bad an alternative is. */
480 101164919 : int *alternative_reject;
481 : /* Vector recording how many registers can be introduced by choosing
482 : this alternative. */
483 101164919 : 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 101164919 : int *op_alt_regno[MAX_RECOG_OPERANDS];
488 : /* Array of alternatives, sorted in order of decreasing desirability. */
489 101164919 : int *alternative_order;
490 :
491 101164919 : extract_constrain_insn (insn);
492 :
493 101164919 : if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
494 : return 0;
495 :
496 87335066 : alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
497 87335066 : alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
498 87335066 : alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
499 87335066 : memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
500 87335066 : memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
501 :
502 : /* For each operand, find out which regs are equivalent. */
503 282077723 : 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 194742657 : 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 194742657 : if (LABEL_P (recog_data.operand[i])
516 194730136 : || (NOTE_P (recog_data.operand[i])
517 116 : && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
518 194730020 : || (CONSTANT_P (recog_data.operand[i])
519 33144413 : && recog_data.operand_mode[i] == VOIDmode))
520 571924 : continue;
521 :
522 194170733 : op = recog_data.operand[i];
523 194170733 : 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 194170733 : if (side_effects_p (op))
571 4542099 : continue;
572 189628634 : v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
573 189628634 : if (! v)
574 125862018 : continue;
575 :
576 187970973 : for (l = v->locs; l; l = l->next)
577 124204357 : if (REG_P (l->loc))
578 66145494 : SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
579 : }
580 :
581 87335066 : alternative_mask preferred = get_preferred_alternatives (insn);
582 282077723 : for (i = 0; i < recog_data.n_operands; i++)
583 : {
584 194742657 : machine_mode mode;
585 194742657 : int regno;
586 194742657 : const char *p;
587 :
588 194742657 : op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
589 2850784177 : for (j = 0; j < recog_data.n_alternatives; j++)
590 2656041520 : op_alt_regno[i][j] = -1;
591 :
592 194742657 : p = constraints[i] = recog_data.constraints[i];
593 194742657 : mode = recog_data.operand_mode[i];
594 :
595 : /* Add the reject values for each alternative given by the constraints
596 : for this operand. */
597 194742657 : j = 0;
598 7702009997 : while (*p != '\0')
599 : {
600 7507267340 : char c = *p++;
601 7507267340 : if (c == ',')
602 2452657022 : j++;
603 5054610318 : else if (c == '?')
604 609363083 : alternative_reject[j] += 3;
605 4445247235 : else if (c == '!')
606 18138076 : 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 194742657 : regno = true_regnum (recog_data.operand[i]);
612 194742657 : if (regno >= 0
613 77980863 : || constraints[i][0] == '='
614 58502167 : || constraints[i][0] == '+')
615 136355033 : continue;
616 :
617 5430049032 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
618 : {
619 5371661408 : enum reg_class rclass = NO_REGS;
620 :
621 5371661408 : if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
622 5370945870 : continue;
623 :
624 715538 : 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 715538 : j = 0;
630 715538 : p = constraints[i];
631 38794353 : for (;;)
632 : {
633 38794353 : char c = *p;
634 :
635 38794353 : switch (c)
636 : {
637 187990 : case 'g':
638 187990 : rclass = reg_class_subunion[rclass][GENERAL_REGS];
639 187990 : break;
640 :
641 24544510 : default:
642 24544510 : rclass
643 24544510 : = (reg_class_subunion
644 24544510 : [rclass]
645 24544510 : [reg_class_for_constraint (lookup_constraint (p))]);
646 24544510 : break;
647 :
648 14061853 : 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 14061853 : if (op_alt_regno[i][j] == -1
654 13992958 : && TEST_BIT (preferred, j)
655 9563396 : && reg_fits_class_p (testreg, rclass, 0, mode)
656 16403099 : && (!CONST_INT_P (recog_data.operand[i])
657 2208184 : || (set_src_cost (recog_data.operand[i], mode,
658 : optimize_bb_for_speed_p
659 2208184 : (BLOCK_FOR_INSN (insn)))
660 2208184 : > set_src_cost (testreg, mode,
661 : optimize_bb_for_speed_p
662 2208184 : (BLOCK_FOR_INSN (insn))))))
663 : {
664 133730 : alternative_nregs[j]++;
665 133730 : op_alt_regno[i][j] = regno;
666 : }
667 14061853 : j++;
668 14061853 : rclass = NO_REGS;
669 14061853 : break;
670 : }
671 38794353 : p += CONSTRAINT_LEN (c, p);
672 :
673 38794353 : 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 87335066 : alternative_order[0] = 0;
682 87335066 : 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 1357990818 : for (i = j = 0; i < recog_data.n_alternatives; i++)
689 1270655752 : if (alternative_reject[i] <= alternative_reject[which_alternative])
690 735713734 : alternative_order[j++] = i;
691 87335066 : 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 735713734 : for (i = 0; i < recog_data.n_alternatives - 1; i++)
696 : {
697 648378668 : int best = i;
698 648378668 : int best_reject = alternative_reject[alternative_order[i]];
699 648378668 : int best_nregs = alternative_nregs[alternative_order[i]];
700 :
701 4489633550 : for (j = i + 1; j < recog_data.n_alternatives; j++)
702 : {
703 3841254882 : int this_reject = alternative_reject[alternative_order[j]];
704 3841254882 : int this_nregs = alternative_nregs[alternative_order[j]];
705 :
706 3841254882 : if (this_reject < best_reject
707 3834659971 : || (this_reject == best_reject && this_nregs > best_nregs))
708 : {
709 6672727 : best = j;
710 6672727 : best_reject = this_reject;
711 6672727 : best_nregs = this_nregs;
712 : }
713 : }
714 :
715 648378668 : 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 87335066 : j = alternative_order[0];
721 :
722 282077723 : for (i = 0; i < recog_data.n_operands; i++)
723 : {
724 194742657 : machine_mode mode = recog_data.operand_mode[i];
725 194742657 : if (op_alt_regno[i][j] == -1)
726 194692825 : continue;
727 :
728 49832 : validate_change (insn, recog_data.operand_loc[i],
729 : gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
730 : }
731 :
732 88639127 : for (i = recog_data.n_dups - 1; i >= 0; i--)
733 : {
734 1304061 : int op = recog_data.dup_num[i];
735 1304061 : machine_mode mode = recog_data.operand_mode[op];
736 :
737 1304061 : if (op_alt_regno[op][j] == -1)
738 1303651 : continue;
739 :
740 410 : validate_change (insn, recog_data.dup_loc[i],
741 : gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
742 : }
743 :
744 87335066 : 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 220854 : reload_combine_split_one_ruid (int *pruid, int split_ruid)
820 : {
821 220854 : if (*pruid > split_ruid)
822 9172 : (*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 781 : reload_combine_split_ruids (int split_ruid)
831 : {
832 781 : unsigned i;
833 :
834 781 : reload_combine_split_one_ruid (&reload_combine_ruid, split_ruid);
835 781 : reload_combine_split_one_ruid (&last_label_ruid, split_ruid);
836 781 : reload_combine_split_one_ruid (&last_jump_ruid, split_ruid);
837 :
838 72633 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
839 : {
840 71852 : int j, idx = reg_state[i].use_index;
841 71852 : reload_combine_split_one_ruid (®_state[i].use_ruid, split_ruid);
842 71852 : reload_combine_split_one_ruid (®_state[i].store_ruid, split_ruid);
843 71852 : reload_combine_split_one_ruid (®_state[i].real_store_ruid,
844 : split_ruid);
845 71852 : if (idx < 0)
846 25828 : continue;
847 48979 : for (j = idx; j < RELOAD_COMBINE_MAX_USES; j++)
848 : {
849 5234 : reload_combine_split_one_ruid (®_state[i].reg_use[j].ruid,
850 : split_ruid);
851 : }
852 : }
853 781 : }
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 5647 : reload_combine_purge_insn_uses (rtx_insn *insn)
861 : {
862 5647 : unsigned i;
863 :
864 525171 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
865 : {
866 519524 : int j, k, idx = reg_state[i].use_index;
867 519524 : if (idx < 0)
868 90306 : continue;
869 : j = k = RELOAD_COMBINE_MAX_USES;
870 471562 : while (j-- > idx)
871 : {
872 42344 : if (reg_state[i].reg_use[j].insn != insn)
873 : {
874 36157 : k--;
875 36157 : if (k != j)
876 4233 : reg_state[i].reg_use[k] = reg_state[i].reg_use[j];
877 : }
878 : }
879 429218 : reg_state[i].use_index = k;
880 : }
881 5647 : }
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 781 : reload_combine_purge_reg_uses_after_ruid (unsigned regno, int ruid)
888 : {
889 781 : int j, k, idx = reg_state[regno].use_index;
890 781 : if (idx < 0)
891 : return;
892 : j = k = RELOAD_COMBINE_MAX_USES;
893 3027 : while (j-- > idx)
894 : {
895 2246 : if (reg_state[regno].reg_use[j].ruid >= ruid)
896 : {
897 1314 : k--;
898 1314 : if (k != j)
899 527 : reg_state[regno].reg_use[k] = reg_state[regno].reg_use[j];
900 : }
901 : }
902 781 : 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 3771284 : reload_combine_closest_single_use (unsigned regno, int ruid_limit)
911 : {
912 3771284 : int i, best_ruid = 0;
913 3771284 : int use_idx = reg_state[regno].use_index;
914 3771284 : struct reg_use *retval;
915 :
916 3771284 : if (use_idx < 0)
917 : return NULL;
918 : retval = NULL;
919 3667280 : for (i = use_idx; i < RELOAD_COMBINE_MAX_USES; i++)
920 : {
921 2121567 : struct reg_use *use = reg_state[regno].reg_use + i;
922 2121567 : int this_ruid = use->ruid;
923 2121567 : if (this_ruid >= ruid_limit)
924 810093 : continue;
925 1311474 : if (this_ruid > best_ruid)
926 : {
927 : best_ruid = this_ruid;
928 : retval = use;
929 : }
930 341190 : else if (this_ruid == best_ruid)
931 2121567 : retval = NULL;
932 : }
933 1545713 : if (last_label_ruid >= best_ruid)
934 647867 : 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 953 : fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
946 : {
947 953 : rtx_insn *insn;
948 7387 : for (insn = from; insn != to; insn = NEXT_INSN (insn))
949 : {
950 6434 : rtx t;
951 :
952 6434 : if (!DEBUG_BIND_INSN_P (insn))
953 5241 : 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 953 : }
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 772731 : try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
967 : {
968 772731 : rtx_insn *use_insn = use->insn;
969 772731 : rtx mem = use->containing_mem;
970 772731 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
971 :
972 772731 : if (mem != NULL_RTX)
973 : {
974 17410 : addr_space_t as = MEM_ADDR_SPACE (mem);
975 17410 : rtx oldaddr = XEXP (mem, 0);
976 17410 : rtx newaddr = NULL_RTX;
977 17410 : int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed);
978 17410 : int new_cost;
979 :
980 17410 : newaddr = simplify_replace_rtx (oldaddr, reg, src);
981 17410 : if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as))
982 : {
983 5159 : XEXP (mem, 0) = newaddr;
984 5159 : new_cost = address_cost (newaddr, GET_MODE (mem), as, speed);
985 5159 : XEXP (mem, 0) = oldaddr;
986 5159 : if (new_cost <= old_cost
987 5159 : && validate_change (use_insn,
988 : &XEXP (mem, 0), newaddr, 0))
989 : return true;
990 : }
991 : }
992 : else
993 : {
994 755321 : rtx new_set = single_set (use_insn);
995 755321 : if (new_set
996 754378 : && REG_P (SET_DEST (new_set))
997 305728 : && GET_CODE (SET_SRC (new_set)) == PLUS
998 21033 : && REG_P (XEXP (SET_SRC (new_set), 0))
999 19018 : && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
1000 : {
1001 1611 : rtx new_src;
1002 1611 : machine_mode mode = GET_MODE (SET_DEST (new_set));
1003 1611 : int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
1004 :
1005 1611 : gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
1006 1611 : new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
1007 :
1008 1611 : if (set_src_cost (new_src, mode, speed) <= old_cost
1009 1611 : && 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 61340713 : reload_combine_recognize_const_pattern (rtx_insn *insn)
1025 : {
1026 61340713 : int from_ruid = reload_combine_ruid;
1027 61340713 : rtx set, pat, reg, src, addreg;
1028 61340713 : unsigned int regno;
1029 61340713 : struct reg_use *use;
1030 61340713 : bool must_move_add;
1031 61340713 : rtx_insn *add_moved_after_insn = NULL;
1032 61340713 : int add_moved_after_ruid = 0;
1033 61340713 : int clobbered_regno = -1;
1034 :
1035 61340713 : set = single_set (insn);
1036 61340713 : if (set == NULL_RTX)
1037 : return false;
1038 :
1039 57200264 : reg = SET_DEST (set);
1040 57200264 : src = SET_SRC (set);
1041 57200264 : if (!REG_P (reg)
1042 38914013 : || REG_NREGS (reg) != 1
1043 44609659 : || GET_MODE (reg) != Pmode
1044 79313015 : || reg == stack_pointer_rtx)
1045 : return false;
1046 :
1047 20408606 : 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 20408606 : if (GET_CODE (src) != PLUS
1054 4000091 : || !REG_P (XEXP (src, 0))
1055 3729146 : || !CONSTANT_P (XEXP (src, 1)))
1056 : return false;
1057 :
1058 3090322 : addreg = XEXP (src, 0);
1059 3090322 : must_move_add = rtx_equal_p (reg, addreg);
1060 :
1061 3090322 : pat = PATTERN (insn);
1062 3090322 : 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 823292 : gcc_assert (GET_CODE (PATTERN (insn)) == PARALLEL);
1069 823292 : if (XVECLEN (pat, 0) != 2 || XVECEXP (pat, 0, 0) != set
1070 823292 : || GET_CODE (XVECEXP (pat, 0, 1)) != CLOBBER
1071 823292 : || !REG_P (XEXP (XVECEXP (pat, 0, 1), 0)))
1072 : return false;
1073 823292 : clobbered_regno = REGNO (XEXP (XVECEXP (pat, 0, 1), 0));
1074 : }
1075 :
1076 3771284 : do
1077 : {
1078 3771284 : use = reload_combine_closest_single_use (regno, from_ruid);
1079 :
1080 3771284 : if (use)
1081 : /* Start the search for the next use from here. */
1082 874261 : from_ruid = use->ruid;
1083 :
1084 1229948 : if (use && GET_MODE (*use->usep) == Pmode)
1085 : {
1086 868459 : bool delete_add = false;
1087 868459 : rtx_insn *use_insn = use->insn;
1088 868459 : int use_ruid = use->ruid;
1089 :
1090 : /* Avoid moving the add insn past a jump. */
1091 868459 : 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 868141 : if (must_move_add && clobbered_regno >= 0
1097 111797 : && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1098 : break;
1099 :
1100 842685 : gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1101 : /* Avoid moving a use of ADDREG past a point where it is stored. */
1102 842685 : 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 772737 : if (must_move_add && reg_state[regno].store_ruid == use_ruid)
1108 : {
1109 28931 : if (use->containing_mem == NULL_RTX)
1110 : delete_add = true;
1111 : else
1112 : break;
1113 : }
1114 :
1115 772731 : if (try_replace_in_use (use, reg, src))
1116 : {
1117 5647 : reload_combine_purge_insn_uses (use_insn);
1118 5647 : reload_combine_note_use (&PATTERN (use_insn), use_insn,
1119 : use_ruid, NULL_RTX);
1120 :
1121 5647 : 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 5592 : if (must_move_add)
1128 : {
1129 1578 : add_moved_after_insn = use_insn;
1130 1578 : add_moved_after_ruid = use_ruid;
1131 : }
1132 5592 : continue;
1133 : }
1134 : }
1135 : /* If we get here, we couldn't handle this use. */
1136 3669909 : if (must_move_add)
1137 : break;
1138 : }
1139 2848983 : while (use);
1140 :
1141 3090267 : if (!must_move_add || add_moved_after_insn == NULL_RTX)
1142 : /* Process the add normally. */
1143 : return false;
1144 :
1145 781 : fixup_debug_insns (reg, src, insn, add_moved_after_insn);
1146 :
1147 781 : reorder_insns (insn, insn, add_moved_after_insn);
1148 781 : reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
1149 781 : reload_combine_split_ruids (add_moved_after_ruid - 1);
1150 781 : reload_combine_note_use (&PATTERN (insn), insn,
1151 : add_moved_after_ruid, NULL_RTX);
1152 781 : reg_state[regno].store_ruid = add_moved_after_ruid;
1153 :
1154 781 : 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 61339877 : reload_combine_recognize_pattern (rtx_insn *insn)
1163 : {
1164 61339877 : rtx set, reg, src;
1165 :
1166 61339877 : set = single_set (insn);
1167 61339877 : if (set == NULL_RTX)
1168 : return false;
1169 :
1170 57199428 : reg = SET_DEST (set);
1171 57199428 : src = SET_SRC (set);
1172 57199428 : if (!REG_P (reg) || REG_NREGS (reg) != 1)
1173 : return false;
1174 :
1175 38300278 : unsigned int regno = REGNO (reg);
1176 38300278 : machine_mode mode = GET_MODE (reg);
1177 :
1178 38300278 : if (reg_state[regno].use_index < 0
1179 38300278 : || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1180 : return false;
1181 :
1182 24788234 : for (int i = reg_state[regno].use_index;
1183 45293159 : i < RELOAD_COMBINE_MAX_USES; i++)
1184 : {
1185 25577327 : struct reg_use *use = reg_state[regno].reg_use + i;
1186 25577327 : if (GET_MODE (*use->usep) != mode)
1187 : return false;
1188 : /* Don't try to adjust (use (REGX)). */
1189 24791933 : if (GET_CODE (PATTERN (use->insn)) == USE
1190 24791933 : && &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 19715832 : if (GET_CODE (src) == PLUS
1209 2364949 : && reg_state[regno].all_offsets_match
1210 2085940 : && last_index_reg != -1
1211 2085940 : && REG_P (XEXP (src, 1))
1212 689115 : && rtx_equal_p (XEXP (src, 0), reg)
1213 499928 : && !rtx_equal_p (XEXP (src, 1), reg)
1214 20208618 : && last_label_ruid < reg_state[regno].use_ruid)
1215 : {
1216 461339 : rtx base = XEXP (src, 1);
1217 461339 : rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1218 461339 : rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1219 461339 : rtx index_reg = NULL_RTX;
1220 461339 : rtx reg_sum = NULL_RTX;
1221 461339 : 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 461339 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
1229 461339 : || 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 8704187 : for (i = first_index_reg; i <= last_index_reg; i++)
1242 : {
1243 8616719 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
1244 3010659 : && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1245 1724288 : && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1246 1709983 : && (crtl->abi->clobbers_full_reg_p (i)
1247 330885 : || df_regs_ever_live_p (i))
1248 1456797 : && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1249 1455755 : && !fixed_regs[i] && !global_regs[i]
1250 530043 : && hard_regno_nregs (i, GET_MODE (reg)) == 1
1251 8750951 : && targetm.hard_regno_scratch_ok (i))
1252 : {
1253 134232 : index_reg = gen_rtx_REG (GET_MODE (reg), i);
1254 134232 : reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1255 134232 : 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 461339 : if (reg_sum
1264 461339 : && prev_set
1265 367523 : && CONST_INT_P (SET_SRC (prev_set))
1266 7715 : && rtx_equal_p (SET_DEST (prev_set), reg)
1267 461339 : && (reg_state[REGNO (base)].store_ruid
1268 2643 : <= reg_state[regno].use_ruid))
1269 : {
1270 : /* Change destination register and, if necessary, the constant
1271 : value in PREV, the constant loading instruction. */
1272 2553 : validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
1273 2553 : 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 5174 : for (i = reg_state[regno].use_index;
1285 5174 : i < RELOAD_COMBINE_MAX_USES; i++)
1286 2621 : 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 2553 : 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 1050468 : reload_combine (void)
1328 : {
1329 1050468 : rtx_insn *insn, *prev;
1330 1050468 : basic_block bb;
1331 1050468 : unsigned int r;
1332 1050468 : int min_labelno, n_labels;
1333 1050468 : 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 1050468 : if (INDEX_REG_CLASS == NO_REGS)
1338 : last_index_reg = -1;
1339 1050468 : else if (first_index_reg == -1 && last_index_reg == 0)
1340 : {
1341 13410693 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1342 13266492 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
1343 : {
1344 4470231 : if (first_index_reg == -1)
1345 144201 : first_index_reg = r;
1346 :
1347 4470231 : last_index_reg = r;
1348 : }
1349 :
1350 : /* If no index register is available, we can quit now. Set LAST_INDEX_REG
1351 : to -1 so we'll know to quit early the next time we get here. */
1352 144201 : if (first_index_reg == -1)
1353 : {
1354 0 : last_index_reg = -1;
1355 0 : return;
1356 : }
1357 : }
1358 :
1359 : /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
1360 : information is a bit fuzzy immediately after reload, but it's
1361 : still good enough to determine which registers are live at a jump
1362 : destination. */
1363 1050468 : min_labelno = get_first_label_num ();
1364 1050468 : n_labels = max_label_num () - min_labelno;
1365 1050468 : label_live = XNEWVEC (HARD_REG_SET, n_labels);
1366 1050468 : CLEAR_HARD_REG_SET (ever_live_at_start);
1367 :
1368 12617674 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
1369 : {
1370 11567206 : insn = BB_HEAD (bb);
1371 11567206 : if (LABEL_P (insn))
1372 : {
1373 5377999 : HARD_REG_SET live;
1374 5377999 : bitmap live_in = df_get_live_in (bb);
1375 :
1376 10755998 : REG_SET_TO_HARD_REG_SET (live, live_in);
1377 5377999 : compute_use_by_pseudos (&live, live_in);
1378 5377999 : LABEL_LIVE (insn) = live;
1379 10755998 : ever_live_at_start |= live;
1380 : }
1381 : }
1382 :
1383 : /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
1384 1050468 : last_label_ruid = last_jump_ruid = reload_combine_ruid = 0;
1385 97693524 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1386 : {
1387 96643056 : reg_state[r].store_ruid = 0;
1388 96643056 : reg_state[r].real_store_ruid = 0;
1389 96643056 : if (fixed_regs[r])
1390 47852485 : reg_state[r].use_index = -1;
1391 : else
1392 48790571 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1393 : }
1394 :
1395 143634935 : for (insn = get_last_insn (); insn; insn = prev)
1396 : {
1397 142584467 : bool control_flow_insn;
1398 142584467 : rtx note;
1399 :
1400 142584467 : prev = PREV_INSN (insn);
1401 :
1402 : /* We cannot do our optimization across labels. Invalidating all the use
1403 : information we have would be costly, so we just note where the label
1404 : is and then later disable any optimization that would cross it. */
1405 142584467 : if (LABEL_P (insn))
1406 5384498 : last_label_ruid = reload_combine_ruid;
1407 137199969 : else if (BARRIER_P (insn))
1408 : {
1409 : /* Crossing a barrier resets all the use information. */
1410 288500136 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1411 285397984 : if (! fixed_regs[r])
1412 139200181 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1413 : }
1414 134097817 : else if (INSN_P (insn) && volatile_insn_p (PATTERN (insn)))
1415 : /* Optimizations across insns being marked as volatile must be
1416 : prevented. All the usage information is invalidated
1417 : here. */
1418 42321789 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1419 41866716 : if (! fixed_regs[r]
1420 19697793 : && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1421 672711 : reg_state[r].use_index = -1;
1422 :
1423 142584467 : if (! NONDEBUG_INSN_P (insn))
1424 81243754 : continue;
1425 :
1426 61340713 : reload_combine_ruid++;
1427 :
1428 61340713 : control_flow_insn = control_flow_insn_p (insn);
1429 61340713 : if (control_flow_insn)
1430 8868629 : last_jump_ruid = reload_combine_ruid;
1431 :
1432 61340713 : if (reload_combine_recognize_const_pattern (insn)
1433 61340713 : || reload_combine_recognize_pattern (insn))
1434 953 : continue;
1435 :
1436 61339760 : note_stores (insn, reload_combine_note_store, NULL);
1437 :
1438 61339760 : if (CALL_P (insn))
1439 : {
1440 4888682 : rtx link;
1441 4888682 : HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
1442 :
1443 454647426 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1444 449758744 : if (TEST_HARD_REG_BIT (used_regs, r))
1445 : {
1446 398815582 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1447 398815582 : reg_state[r].store_ruid = reload_combine_ruid;
1448 : }
1449 :
1450 15232628 : for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1451 10343946 : link = XEXP (link, 1))
1452 : {
1453 10343946 : rtx setuse = XEXP (link, 0);
1454 10343946 : rtx usage_rtx = XEXP (setuse, 0);
1455 :
1456 10343946 : if (GET_CODE (setuse) == USE && REG_P (usage_rtx))
1457 : {
1458 8945416 : unsigned int end_regno = END_REGNO (usage_rtx);
1459 17946588 : for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1460 9001172 : reg_state[i].use_index = -1;
1461 : }
1462 : }
1463 : }
1464 :
1465 61339760 : if (control_flow_insn && !ANY_RETURN_P (PATTERN (insn)))
1466 : {
1467 : /* Non-spill registers might be used at the call destination in
1468 : some unknown fashion, so we have to mark the unknown use. */
1469 8868629 : HARD_REG_SET *live;
1470 :
1471 10285878 : if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1472 8868712 : && JUMP_LABEL (insn))
1473 : {
1474 7451463 : if (ANY_RETURN_P (JUMP_LABEL (insn)))
1475 : live = NULL;
1476 : else
1477 7451463 : live = &LABEL_LIVE (JUMP_LABEL (insn));
1478 : }
1479 : else
1480 : live = &ever_live_at_start;
1481 :
1482 8868629 : if (live)
1483 824782497 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1484 815913868 : if (TEST_HARD_REG_BIT (*live, r))
1485 44603440 : reg_state[r].use_index = -1;
1486 : }
1487 :
1488 61339760 : reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1489 : NULL_RTX);
1490 :
1491 85393877 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1492 : {
1493 24054117 : if (REG_NOTE_KIND (note) == REG_INC && REG_P (XEXP (note, 0)))
1494 : {
1495 0 : int regno = REGNO (XEXP (note, 0));
1496 0 : reg_state[regno].store_ruid = reload_combine_ruid;
1497 0 : reg_state[regno].real_store_ruid = reload_combine_ruid;
1498 0 : reg_state[regno].use_index = -1;
1499 : }
1500 : }
1501 : }
1502 :
1503 1050468 : free (label_live);
1504 : }
1505 :
1506 : /* Check if DST is a register or a subreg of a register; if it is,
1507 : update store_ruid, real_store_ruid and use_index in the reg_state
1508 : structure accordingly. Called via note_stores from reload_combine. */
1509 :
1510 : static void
1511 65950342 : reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1512 : {
1513 65950342 : int regno = 0;
1514 65950342 : int i;
1515 65950342 : machine_mode mode = GET_MODE (dst);
1516 :
1517 65950342 : if (GET_CODE (dst) == SUBREG)
1518 : {
1519 7420 : regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1520 3710 : GET_MODE (SUBREG_REG (dst)),
1521 3710 : SUBREG_BYTE (dst),
1522 : GET_MODE (dst));
1523 3710 : dst = SUBREG_REG (dst);
1524 : }
1525 :
1526 : /* Some targets do argument pushes without adding REG_INC notes. */
1527 :
1528 65950342 : if (MEM_P (dst))
1529 : {
1530 10932310 : dst = XEXP (dst, 0);
1531 10932310 : if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1532 10932310 : || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1533 9290472 : || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1534 : {
1535 1711423 : unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1536 3422846 : for (unsigned int i = REGNO (XEXP (dst, 0)); i < end_regno; ++i)
1537 : {
1538 : /* We could probably do better, but for now mark the register
1539 : as used in an unknown fashion and set/clobbered at this
1540 : insn. */
1541 1711423 : reg_state[i].use_index = -1;
1542 1711423 : reg_state[i].store_ruid = reload_combine_ruid;
1543 1711423 : reg_state[i].real_store_ruid = reload_combine_ruid;
1544 : }
1545 : }
1546 : else
1547 : return;
1548 : }
1549 :
1550 56729455 : if (!REG_P (dst))
1551 : return;
1552 47554433 : regno += REGNO (dst);
1553 :
1554 : /* note_stores might have stripped a STRICT_LOW_PART, so we have to be
1555 : careful with registers / register parts that are not full words.
1556 : Similarly for ZERO_EXTRACT. */
1557 47554433 : if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1558 47553326 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1559 : {
1560 8766 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1561 : {
1562 4383 : reg_state[i].use_index = -1;
1563 4383 : reg_state[i].store_ruid = reload_combine_ruid;
1564 4383 : reg_state[i].real_store_ruid = reload_combine_ruid;
1565 : }
1566 : }
1567 : else
1568 : {
1569 95721470 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1570 : {
1571 48171420 : reg_state[i].store_ruid = reload_combine_ruid;
1572 48171420 : if (GET_CODE (set) == SET)
1573 40366165 : reg_state[i].real_store_ruid = reload_combine_ruid;
1574 48171420 : reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
1575 : }
1576 : }
1577 : }
1578 :
1579 : /* XP points to a piece of rtl that has to be checked for any uses of
1580 : registers.
1581 : *XP is the pattern of INSN, or a part of it.
1582 : Called from reload_combine, and recursively by itself. */
1583 : static void
1584 218023889 : reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1585 : {
1586 257757210 : rtx x = *xp;
1587 257757210 : enum rtx_code code = x->code;
1588 257757210 : const char *fmt;
1589 257757210 : int i, j;
1590 257757210 : rtx offset = const0_rtx; /* For the REG case below. */
1591 :
1592 257757210 : switch (code)
1593 : {
1594 58096682 : case SET:
1595 58096682 : if (REG_P (SET_DEST (x)))
1596 : {
1597 39733321 : reload_combine_note_use (&SET_SRC (x), insn, ruid, NULL_RTX);
1598 39733321 : return;
1599 : }
1600 : break;
1601 :
1602 648893 : case USE:
1603 : /* If this is the USE of a return value, we can't change it. */
1604 648893 : if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
1605 : {
1606 : /* Mark the return register as used in an unknown fashion. */
1607 558824 : rtx reg = XEXP (x, 0);
1608 558824 : unsigned int end_regno = END_REGNO (reg);
1609 1145699 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1610 586875 : reg_state[regno].use_index = -1;
1611 : return;
1612 : }
1613 : break;
1614 :
1615 7432548 : case CLOBBER:
1616 7432548 : if (REG_P (SET_DEST (x)))
1617 : {
1618 : /* No spurious CLOBBERs of pseudo registers may remain. */
1619 7381037 : gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1620 : return;
1621 : }
1622 : break;
1623 :
1624 23457284 : case PLUS:
1625 : /* We are interested in (plus (reg) (const_int)) . */
1626 23457284 : if (!REG_P (XEXP (x, 0))
1627 21010109 : || !CONST_INT_P (XEXP (x, 1)))
1628 : break;
1629 : offset = XEXP (x, 1);
1630 : x = XEXP (x, 0);
1631 : /* Fall through. */
1632 60147468 : case REG:
1633 60147468 : {
1634 60147468 : int regno = REGNO (x);
1635 60147468 : int use_index;
1636 60147468 : int nregs;
1637 :
1638 : /* No spurious USEs of pseudo registers may remain. */
1639 60147468 : gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1640 :
1641 60147468 : nregs = REG_NREGS (x);
1642 :
1643 : /* We can't substitute into multi-hard-reg uses. */
1644 60147468 : if (nregs > 1)
1645 : {
1646 1227969 : while (--nregs >= 0)
1647 818646 : reg_state[regno + nregs].use_index = -1;
1648 : return;
1649 : }
1650 :
1651 : /* We may be called to update uses in previously seen insns.
1652 : Don't add uses beyond the last store we saw. */
1653 59738145 : if (ruid < reg_state[regno].store_ruid)
1654 : return;
1655 :
1656 : /* If this register is already used in some unknown fashion, we
1657 : can't do anything.
1658 : If we decrement the index from zero to -1, we can't store more
1659 : uses, so this register becomes used in an unknown fashion. */
1660 59737032 : use_index = --reg_state[regno].use_index;
1661 59737032 : if (use_index < 0)
1662 : return;
1663 :
1664 36077676 : if (use_index == RELOAD_COMBINE_MAX_USES - 1)
1665 : {
1666 : /* This is the first use of this register we have seen since we
1667 : marked it as dead. */
1668 27291587 : reg_state[regno].offset = offset;
1669 27291587 : reg_state[regno].all_offsets_match = true;
1670 27291587 : reg_state[regno].use_ruid = ruid;
1671 : }
1672 : else
1673 : {
1674 8786089 : if (reg_state[regno].use_ruid > ruid)
1675 608 : reg_state[regno].use_ruid = ruid;
1676 :
1677 8786089 : if (! rtx_equal_p (offset, reg_state[regno].offset))
1678 3993378 : reg_state[regno].all_offsets_match = false;
1679 : }
1680 :
1681 36077676 : reg_state[regno].reg_use[use_index].insn = insn;
1682 36077676 : reg_state[regno].reg_use[use_index].ruid = ruid;
1683 36077676 : reg_state[regno].reg_use[use_index].containing_mem = containing_mem;
1684 36077676 : reg_state[regno].reg_use[use_index].usep = xp;
1685 36077676 : return;
1686 : }
1687 :
1688 : case MEM:
1689 149936560 : containing_mem = x;
1690 : break;
1691 :
1692 : default:
1693 : break;
1694 : }
1695 :
1696 : /* Recursively process the components of X. */
1697 149936560 : fmt = GET_RTX_FORMAT (code);
1698 383306628 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1699 : {
1700 233370068 : if (fmt[i] == 'e')
1701 136606551 : reload_combine_note_use (&XEXP (x, i), insn, ruid, containing_mem);
1702 96763517 : else if (fmt[i] == 'E')
1703 : {
1704 29820670 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1705 20071013 : reload_combine_note_use (&XVECEXP (x, i, j), insn, ruid,
1706 : containing_mem);
1707 : }
1708 : }
1709 : }
1710 :
1711 : /* See if we can reduce the cost of a constant by replacing a move
1712 : with an add. We track situations in which a register is set to a
1713 : constant or to a register plus a constant. */
1714 : /* We cannot do our optimization across labels. Invalidating all the
1715 : information about register contents we have would be costly, so we
1716 : use move2add_last_label_luid to note where the label is and then
1717 : later disable any optimization that would cross it.
1718 : reg_offset[n] / reg_base_reg[n] / reg_symbol_ref[n] / reg_mode[n]
1719 : are only valid if reg_set_luid[n] is greater than
1720 : move2add_last_label_luid.
1721 : For a set that established a new (potential) base register with
1722 : non-constant value, we use move2add_luid from the place where the
1723 : setting insn is encountered; registers based off that base then
1724 : get the same reg_set_luid. Constants all get
1725 : move2add_last_label_luid + 1 as their reg_set_luid. */
1726 : static int reg_set_luid[FIRST_PSEUDO_REGISTER];
1727 :
1728 : /* If reg_base_reg[n] is negative, register n has been set to
1729 : reg_offset[n] or reg_symbol_ref[n] + reg_offset[n] in mode reg_mode[n].
1730 : If reg_base_reg[n] is non-negative, register n has been set to the
1731 : sum of reg_offset[n] and the value of register reg_base_reg[n]
1732 : before reg_set_luid[n], calculated in mode reg_mode[n] .
1733 : For multi-hard-register registers, all but the first one are
1734 : recorded as BLKmode in reg_mode. Setting reg_mode to VOIDmode
1735 : marks it as invalid. */
1736 : static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
1737 : static int reg_base_reg[FIRST_PSEUDO_REGISTER];
1738 : static rtx reg_symbol_ref[FIRST_PSEUDO_REGISTER];
1739 : static machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
1740 :
1741 : /* move2add_luid is linearly increased while scanning the instructions
1742 : from first to last. It is used to set reg_set_luid in
1743 : reload_cse_move2add and move2add_note_store. */
1744 : static int move2add_luid;
1745 :
1746 : /* move2add_last_label_luid is set whenever a label is found. Labels
1747 : invalidate all previously collected reg_offset data. */
1748 : static int move2add_last_label_luid;
1749 :
1750 : /* ??? We don't know how zero / sign extension is handled, hence we
1751 : can't go from a narrower to a wider mode. */
1752 : #define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
1753 : (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
1754 : || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
1755 : && TRULY_NOOP_TRUNCATION_MODES_P (OUTMODE, INMODE)))
1756 :
1757 : /* Record that REG is being set to a value with the mode of REG. */
1758 :
1759 : static void
1760 52730016 : move2add_record_mode (rtx reg)
1761 : {
1762 52730016 : int regno, nregs;
1763 52730016 : machine_mode mode = GET_MODE (reg);
1764 :
1765 52730016 : if (GET_CODE (reg) == SUBREG)
1766 : {
1767 3649 : regno = subreg_regno (reg);
1768 3649 : nregs = subreg_nregs (reg);
1769 : }
1770 52726367 : else if (REG_P (reg))
1771 : {
1772 52726367 : regno = REGNO (reg);
1773 52726367 : nregs = REG_NREGS (reg);
1774 : }
1775 : else
1776 0 : gcc_unreachable ();
1777 53380897 : for (int i = nregs - 1; i > 0; i--)
1778 650881 : reg_mode[regno + i] = BLKmode;
1779 52730016 : reg_mode[regno] = mode;
1780 52730016 : }
1781 :
1782 : /* Record that REG is being set to the sum of SYM and OFF. */
1783 :
1784 : static void
1785 2084444 : move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1786 : {
1787 2084444 : int regno = REGNO (reg);
1788 :
1789 2084444 : move2add_record_mode (reg);
1790 2084444 : reg_set_luid[regno] = move2add_luid;
1791 2084444 : reg_base_reg[regno] = -1;
1792 2084444 : reg_symbol_ref[regno] = sym;
1793 2084444 : reg_offset[regno] = INTVAL (off);
1794 2084444 : }
1795 :
1796 : /* Check if REGNO contains a valid value in MODE. */
1797 :
1798 : static bool
1799 209638712 : move2add_valid_value_p (int regno, scalar_int_mode mode)
1800 : {
1801 209638712 : if (reg_set_luid[regno] <= move2add_last_label_luid)
1802 : return false;
1803 :
1804 21232497 : if (mode != reg_mode[regno])
1805 : {
1806 11337944 : scalar_int_mode old_mode;
1807 11337944 : if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1808 7232804 : || !MODES_OK_FOR_MOVE2ADD (mode, old_mode)
1809 521329 : || !REG_CAN_CHANGE_MODE_P (regno, old_mode, mode))
1810 10816615 : return false;
1811 : /* The value loaded into regno in reg_mode[regno] is also valid in
1812 : mode after truncation only if (REG:mode regno) is the lowpart of
1813 : (REG:reg_mode[regno] regno). Now, for big endian, the starting
1814 : regno of the lowpart might be different. */
1815 521329 : poly_int64 s_off = subreg_lowpart_offset (mode, old_mode);
1816 521329 : s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1817 521329 : if (maybe_ne (s_off, 0))
1818 : /* We could in principle adjust regno, check reg_mode[regno] to be
1819 : BLKmode, and return s_off to the caller (vs. -1 for failure),
1820 : but we currently have no callers that could make use of this
1821 : information. */
1822 : return false;
1823 : }
1824 :
1825 10467134 : for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1826 55314 : if (reg_mode[i] != BLKmode)
1827 : return false;
1828 : return true;
1829 : }
1830 :
1831 : /* This function is called with INSN that sets REG (of mode MODE)
1832 : to (SYM + OFF), while REG is known to already have value (SYM + offset).
1833 : This function tries to change INSN into an add instruction
1834 : (set (REG) (plus (REG) (OFF - offset))) using the known value.
1835 : It also updates the information about REG's known value.
1836 : Return true if we made a change. */
1837 :
1838 : static bool
1839 153136 : move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1840 : rtx_insn *insn)
1841 : {
1842 153136 : rtx set = single_set (insn);
1843 153136 : rtx src = SET_SRC (set);
1844 153136 : int regno = REGNO (reg);
1845 153136 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1846 153136 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1847 153136 : bool changed = false;
1848 :
1849 : /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1850 : use (set (reg) (reg)) instead.
1851 : We don't delete this insn, nor do we convert it into a
1852 : note, to avoid losing register notes or the return
1853 : value flag. jump2 already knows how to get rid of
1854 : no-op moves. */
1855 153136 : if (new_src == const0_rtx)
1856 : {
1857 : /* If the constants are different, this is a
1858 : truncation, that, if turned into (set (reg)
1859 : (reg)), would be discarded. Maybe we should
1860 : try a truncMN pattern? */
1861 25390 : if (INTVAL (off) == reg_offset [regno])
1862 23279 : changed = validate_change (insn, &SET_SRC (set), reg, 0);
1863 : }
1864 : else
1865 : {
1866 127746 : struct full_rtx_costs oldcst, newcst;
1867 127746 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1868 :
1869 127746 : get_full_set_rtx_cost (set, &oldcst);
1870 127746 : SET_SRC (set) = tem;
1871 127746 : get_full_set_rtx_cost (set, &newcst);
1872 127746 : SET_SRC (set) = src;
1873 :
1874 127746 : if (costs_lt_p (&newcst, &oldcst, speed)
1875 127746 : && have_add2_insn (reg, new_src))
1876 3088 : changed = validate_change (insn, &SET_SRC (set), tem, 0);
1877 124658 : else if (sym == NULL_RTX && mode != BImode)
1878 : {
1879 123198 : scalar_int_mode narrow_mode;
1880 414462 : FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1881 : {
1882 291264 : if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1883 291264 : && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1884 216318 : == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1885 : {
1886 93611 : rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1887 93611 : rtx narrow_src = gen_int_mode (INTVAL (off),
1888 : narrow_mode);
1889 93611 : rtx new_set
1890 93611 : = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1891 : narrow_reg),
1892 : narrow_src);
1893 93611 : get_full_set_rtx_cost (new_set, &newcst);
1894 :
1895 : /* We perform this replacement only if NEXT is either a
1896 : naked SET, or else its single_set is the first element
1897 : in a PARALLEL. */
1898 93611 : rtx *setloc = GET_CODE (PATTERN (insn)) == PARALLEL
1899 93611 : ? &XVECEXP (PATTERN (insn), 0, 0) : &PATTERN (insn);
1900 93611 : if (*setloc == set && costs_lt_p (&newcst, &oldcst, speed))
1901 : {
1902 0 : changed = validate_change (insn, setloc, new_set, 0);
1903 0 : if (changed)
1904 : break;
1905 : }
1906 : }
1907 : }
1908 : }
1909 : }
1910 153136 : move2add_record_sym_value (reg, sym, off);
1911 153136 : return changed;
1912 : }
1913 :
1914 :
1915 : /* This function is called with INSN that sets REG (of mode MODE) to
1916 : (SYM + OFF), but REG doesn't have known value (SYM + offset). This
1917 : function tries to find another register which is known to already have
1918 : value (SYM + offset) and change INSN into an add instruction
1919 : (set (REG) (plus (the found register) (OFF - offset))) if such
1920 : a register is found. It also updates the information about
1921 : REG's known value.
1922 : Return true iff we made a change. */
1923 :
1924 : static bool
1925 1850787 : move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1926 : rtx_insn *insn)
1927 : {
1928 1850787 : rtx set = single_set (insn);
1929 1850787 : rtx src = SET_SRC (set);
1930 1850787 : int regno = REGNO (reg);
1931 1850787 : int min_regno = 0;
1932 1850787 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1933 1850787 : int i;
1934 1850787 : bool changed = false;
1935 1850787 : struct full_rtx_costs oldcst, newcst, mincst;
1936 1850787 : rtx plus_expr;
1937 :
1938 1850787 : init_costs_to_max (&mincst);
1939 1850787 : get_full_set_rtx_cost (set, &oldcst);
1940 :
1941 1850787 : plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1942 1850787 : SET_SRC (set) = plus_expr;
1943 :
1944 172122772 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1945 170271991 : if (move2add_valid_value_p (i, mode)
1946 3666809 : && reg_base_reg[i] < 0
1947 1446654 : && reg_symbol_ref[i] != NULL_RTX
1948 171255124 : && rtx_equal_p (sym, reg_symbol_ref[i]))
1949 : {
1950 36720 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1951 18360 : GET_MODE (reg));
1952 : /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1953 : use (set (reg) (reg)) instead.
1954 : We don't delete this insn, nor do we convert it into a
1955 : note, to avoid losing register notes or the return
1956 : value flag. jump2 already knows how to get rid of
1957 : no-op moves. */
1958 18360 : if (new_src == const0_rtx)
1959 : {
1960 6 : init_costs_to_zero (&mincst);
1961 6 : min_regno = i;
1962 6 : break;
1963 : }
1964 : else
1965 : {
1966 18354 : XEXP (plus_expr, 1) = new_src;
1967 18354 : get_full_set_rtx_cost (set, &newcst);
1968 :
1969 18354 : if (costs_lt_p (&newcst, &mincst, speed))
1970 : {
1971 17808 : mincst = newcst;
1972 17808 : min_regno = i;
1973 : }
1974 : }
1975 : }
1976 1850787 : SET_SRC (set) = src;
1977 :
1978 1850787 : if (costs_lt_p (&mincst, &oldcst, speed))
1979 : {
1980 44 : rtx tem;
1981 :
1982 44 : tem = gen_rtx_REG (GET_MODE (reg), min_regno);
1983 44 : if (i != min_regno)
1984 : {
1985 76 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[min_regno],
1986 38 : GET_MODE (reg));
1987 38 : tem = gen_rtx_PLUS (GET_MODE (reg), tem, new_src);
1988 : }
1989 44 : if (validate_change (insn, &SET_SRC (set), tem, 0))
1990 1850787 : changed = true;
1991 : }
1992 1850787 : reg_set_luid[regno] = move2add_luid;
1993 1850787 : move2add_record_sym_value (reg, sym, off);
1994 1850787 : return changed;
1995 : }
1996 :
1997 : /* Perform any invalidations necessary for INSN. */
1998 :
1999 : static void
2000 103933691 : reload_cse_move2add_invalidate (rtx_insn *insn)
2001 : {
2002 126477596 : for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
2003 : {
2004 22543905 : if (REG_NOTE_KIND (note) == REG_INC
2005 0 : && REG_P (XEXP (note, 0)))
2006 : {
2007 : /* Reset the information about this register. */
2008 0 : int regno = REGNO (XEXP (note, 0));
2009 0 : if (regno < FIRST_PSEUDO_REGISTER)
2010 : {
2011 0 : move2add_record_mode (XEXP (note, 0));
2012 0 : reg_mode[regno] = VOIDmode;
2013 : }
2014 : }
2015 : }
2016 :
2017 : /* There are no REG_INC notes for SP autoinc. */
2018 103933691 : subrtx_var_iterator::array_type array;
2019 532620062 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
2020 : {
2021 428686371 : rtx mem = *iter;
2022 428686371 : if (mem
2023 428686371 : && MEM_P (mem)
2024 27719126 : && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
2025 : {
2026 1671409 : if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
2027 1671409 : reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
2028 : }
2029 : }
2030 :
2031 103933691 : note_stores (insn, move2add_note_store, insn);
2032 :
2033 : /* If INSN is a conditional branch, we try to extract an
2034 : implicit set out of it. */
2035 103933691 : if (any_condjump_p (insn))
2036 : {
2037 4792547 : rtx cnd = fis_get_condition (insn);
2038 :
2039 4792547 : if (cnd != NULL_RTX
2040 4290901 : && GET_CODE (cnd) == NE
2041 1908256 : && REG_P (XEXP (cnd, 0))
2042 1268151 : && !reg_set_p (XEXP (cnd, 0), insn)
2043 : /* The following two checks, which are also in
2044 : move2add_note_store, are intended to reduce the
2045 : number of calls to gen_rtx_SET to avoid memory
2046 : allocation if possible. */
2047 1268151 : && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2048 1268150 : && REG_NREGS (XEXP (cnd, 0)) == 1
2049 6060697 : && CONST_INT_P (XEXP (cnd, 1)))
2050 : {
2051 854434 : rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2052 854434 : move2add_note_store (SET_DEST (implicit_set), implicit_set, insn);
2053 : }
2054 : }
2055 :
2056 : /* If this is a CALL_INSN, all call used registers are stored with
2057 : unknown values. */
2058 103933691 : if (CALL_P (insn))
2059 : {
2060 4617544 : function_abi callee_abi = insn_callee_abi (insn);
2061 429431592 : for (int i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2062 424814048 : if (reg_mode[i] != VOIDmode
2063 21496976 : && reg_mode[i] != BLKmode
2064 445760894 : && callee_abi.clobbers_reg_p (reg_mode[i], i))
2065 : /* Reset the information about this register. */
2066 7926422 : reg_mode[i] = VOIDmode;
2067 : }
2068 103933691 : }
2069 :
2070 : /* Convert move insns with constant inputs to additions if they are cheaper.
2071 : Return true if any changes were made. */
2072 : static bool
2073 1041492 : reload_cse_move2add (rtx_insn *first)
2074 : {
2075 1041492 : int i;
2076 1041492 : rtx_insn *insn;
2077 1041492 : bool changed = false;
2078 :
2079 96858756 : for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2080 : {
2081 95817264 : reg_set_luid[i] = 0;
2082 95817264 : reg_offset[i] = 0;
2083 95817264 : reg_base_reg[i] = 0;
2084 95817264 : reg_symbol_ref[i] = NULL_RTX;
2085 95817264 : reg_mode[i] = VOIDmode;
2086 : }
2087 :
2088 1041492 : move2add_last_label_luid = 0;
2089 1041492 : move2add_luid = 2;
2090 134751870 : for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
2091 : {
2092 133710378 : rtx set;
2093 :
2094 133710378 : if (LABEL_P (insn))
2095 : {
2096 5086374 : move2add_last_label_luid = move2add_luid;
2097 : /* We're going to increment move2add_luid twice after a
2098 : label, so that we can use move2add_last_label_luid + 1 as
2099 : the luid for constants. */
2100 5086374 : move2add_luid++;
2101 138796752 : continue;
2102 : }
2103 128624004 : if (! INSN_P (insn))
2104 22686390 : continue;
2105 105937614 : set = single_set (insn);
2106 : /* For simplicity, we only perform this optimization on
2107 : single-sets. */
2108 105937614 : scalar_int_mode mode;
2109 105937614 : if (set
2110 53847465 : && REG_P (SET_DEST (set))
2111 142581615 : && is_a <scalar_int_mode> (GET_MODE (SET_DEST (set)), &mode))
2112 : {
2113 27114596 : rtx reg = SET_DEST (set);
2114 27114596 : int regno = REGNO (reg);
2115 27114596 : rtx src = SET_SRC (set);
2116 :
2117 : /* Check if we have valid information on the contents of this
2118 : register in the mode of REG. */
2119 27114596 : if (move2add_valid_value_p (regno, mode)
2120 27114596 : && dbg_cnt (cse2_move2add))
2121 : {
2122 : /* Try to transform (set (REGX) (CONST_INT A))
2123 : ...
2124 : (set (REGX) (CONST_INT B))
2125 : to
2126 : (set (REGX) (CONST_INT A))
2127 : ...
2128 : (set (REGX) (plus (REGX) (CONST_INT B-A)))
2129 : or
2130 : (set (REGX) (CONST_INT A))
2131 : ...
2132 : (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
2133 : */
2134 :
2135 3799124 : if (CONST_INT_P (src)
2136 328935 : && reg_base_reg[regno] < 0
2137 153729 : && reg_symbol_ref[regno] == NULL_RTX)
2138 : {
2139 151364 : changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
2140 : src, insn);
2141 151364 : continue;
2142 : }
2143 :
2144 : /* Try to transform (set (REGX) (REGY))
2145 : (set (REGX) (PLUS (REGX) (CONST_INT A)))
2146 : ...
2147 : (set (REGX) (REGY))
2148 : (set (REGX) (PLUS (REGX) (CONST_INT B)))
2149 : to
2150 : (set (REGX) (REGY))
2151 : (set (REGX) (PLUS (REGX) (CONST_INT A)))
2152 : ...
2153 : (set (REGX) (plus (REGX) (CONST_INT B-A))) */
2154 3647760 : else if (REG_P (src)
2155 454907 : && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
2156 117538 : && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
2157 3765298 : && move2add_valid_value_p (REGNO (src), mode))
2158 : {
2159 91285 : rtx_insn *next = next_nonnote_nondebug_insn (insn);
2160 91285 : rtx set = NULL_RTX;
2161 91285 : if (next)
2162 91274 : set = single_set (next);
2163 91274 : if (set
2164 70501 : && SET_DEST (set) == reg
2165 7056 : && GET_CODE (SET_SRC (set)) == PLUS
2166 781 : && XEXP (SET_SRC (set), 0) == reg
2167 776 : && CONST_INT_P (XEXP (SET_SRC (set), 1)))
2168 : {
2169 529 : rtx src3 = XEXP (SET_SRC (set), 1);
2170 529 : unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
2171 529 : HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
2172 529 : HOST_WIDE_INT regno_offset = reg_offset[regno];
2173 529 : rtx new_src =
2174 1058 : gen_int_mode (added_offset
2175 529 : + base_offset
2176 529 : - regno_offset,
2177 : mode);
2178 529 : bool success = false;
2179 529 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
2180 :
2181 529 : if (new_src == const0_rtx)
2182 : /* See above why we create (set (reg) (reg)) here. */
2183 37 : success
2184 37 : = validate_change (next, &SET_SRC (set), reg, 0);
2185 : else
2186 : {
2187 492 : rtx old_src = SET_SRC (set);
2188 492 : struct full_rtx_costs oldcst, newcst;
2189 492 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
2190 :
2191 492 : get_full_set_rtx_cost (set, &oldcst);
2192 492 : SET_SRC (set) = tem;
2193 492 : get_full_set_src_cost (tem, mode, &newcst);
2194 492 : SET_SRC (set) = old_src;
2195 492 : costs_add_n_insns (&oldcst, 1);
2196 :
2197 492 : rtx *setloc = GET_CODE (PATTERN (next)) == PARALLEL
2198 492 : ? &XVECEXP (PATTERN (next), 0, 0) : &PATTERN (next);
2199 492 : if (*setloc == set
2200 492 : && costs_lt_p (&newcst, &oldcst, speed)
2201 984 : && have_add2_insn (reg, new_src))
2202 : {
2203 492 : rtx newpat = gen_rtx_SET (reg, tem);
2204 492 : success
2205 492 : = validate_change (next, setloc, newpat, 0);
2206 : }
2207 : }
2208 529 : if (success)
2209 529 : delete_insn (insn);
2210 529 : changed |= success;
2211 529 : insn = next;
2212 : /* Make sure to perform any invalidations related to
2213 : NEXT/INSN since we're going to bypass the normal
2214 : flow with the continue below.
2215 :
2216 : Do this before recording the new mode/offset. */
2217 529 : reload_cse_move2add_invalidate (insn);
2218 529 : move2add_record_mode (reg);
2219 529 : reg_offset[regno]
2220 529 : = trunc_int_for_mode (added_offset + base_offset,
2221 : mode);
2222 529 : continue;
2223 529 : }
2224 : }
2225 : }
2226 :
2227 : /* Try to transform
2228 : (set (REGX) (CONST (PLUS (SYMBOL_REF) (CONST_INT A))))
2229 : ...
2230 : (set (REGY) (CONST (PLUS (SYMBOL_REF) (CONST_INT B))))
2231 : to
2232 : (set (REGX) (CONST (PLUS (SYMBOL_REF) (CONST_INT A))))
2233 : ...
2234 : (set (REGY) (CONST (PLUS (REGX) (CONST_INT B-A)))) */
2235 26962703 : if ((GET_CODE (src) == SYMBOL_REF
2236 25169823 : || (GET_CODE (src) == CONST
2237 59920 : && GET_CODE (XEXP (src, 0)) == PLUS
2238 59699 : && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF
2239 59679 : && CONST_INT_P (XEXP (XEXP (src, 0), 1))))
2240 27022382 : && dbg_cnt (cse2_move2add))
2241 : {
2242 1852559 : rtx sym, off;
2243 :
2244 1852559 : if (GET_CODE (src) == SYMBOL_REF)
2245 : {
2246 1792880 : sym = src;
2247 1792880 : off = const0_rtx;
2248 : }
2249 : else
2250 : {
2251 59679 : sym = XEXP (XEXP (src, 0), 0);
2252 59679 : off = XEXP (XEXP (src, 0), 1);
2253 : }
2254 :
2255 : /* If the reg already contains the value which is sum of
2256 : sym and some constant value, we can use an add2 insn. */
2257 1852559 : if (move2add_valid_value_p (regno, mode)
2258 191565 : && reg_base_reg[regno] < 0
2259 125743 : && reg_symbol_ref[regno] != NULL_RTX
2260 1904101 : && rtx_equal_p (sym, reg_symbol_ref[regno]))
2261 1772 : changed |= move2add_use_add2_insn (mode, reg, sym, off, insn);
2262 :
2263 : /* Otherwise, we have to find a register whose value is sum
2264 : of sym and some constant value. */
2265 : else
2266 1850787 : changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2267 :
2268 1852559 : continue;
2269 1852559 : }
2270 : }
2271 103933162 : reload_cse_move2add_invalidate (insn);
2272 : }
2273 1041492 : return changed;
2274 : }
2275 :
2276 : /* SET is a SET or CLOBBER that sets DST. DATA is the insn which
2277 : contains SET.
2278 : Update reg_set_luid, reg_offset and reg_base_reg accordingly.
2279 : Called from reload_cse_move2add via note_stores. */
2280 :
2281 : static void
2282 61055107 : move2add_note_store (rtx dst, const_rtx set, void *data)
2283 : {
2284 61055107 : rtx_insn *insn = (rtx_insn *) data;
2285 61055107 : unsigned int regno = 0;
2286 61055107 : scalar_int_mode mode;
2287 :
2288 61055107 : if (GET_CODE (dst) == SUBREG)
2289 3649 : regno = subreg_regno (dst);
2290 61051458 : else if (REG_P (dst))
2291 43747137 : regno = REGNO (dst);
2292 : else
2293 61055107 : return;
2294 :
2295 43750786 : if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2296 16650985 : goto invalidate;
2297 :
2298 27099801 : if (GET_CODE (set) == SET)
2299 : {
2300 26548781 : rtx note, sym = NULL_RTX;
2301 26548781 : rtx off;
2302 :
2303 26548781 : note = find_reg_equal_equiv_note (insn);
2304 26548781 : if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2305 : {
2306 70243 : sym = XEXP (note, 0);
2307 70243 : off = const0_rtx;
2308 : }
2309 4170438 : else if (note && GET_CODE (XEXP (note, 0)) == CONST
2310 10503 : && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2311 10298 : && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2312 10278 : && CONST_INT_P (XEXP (XEXP (XEXP (note, 0), 0), 1)))
2313 : {
2314 : sym = XEXP (XEXP (XEXP (note, 0), 0), 0);
2315 : off = XEXP (XEXP (XEXP (note, 0), 0), 1);
2316 : }
2317 :
2318 80521 : if (sym != NULL_RTX)
2319 : {
2320 80521 : move2add_record_sym_value (dst, sym, off);
2321 80521 : return;
2322 : }
2323 : }
2324 :
2325 27019280 : if (GET_CODE (set) == SET
2326 26468260 : && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2327 26467211 : && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2328 : {
2329 26464111 : rtx src = SET_SRC (set);
2330 26464111 : rtx base_reg;
2331 26464111 : unsigned HOST_WIDE_INT offset;
2332 26464111 : int base_regno;
2333 :
2334 26464111 : switch (GET_CODE (src))
2335 : {
2336 5965994 : case PLUS:
2337 5965994 : if (REG_P (XEXP (src, 0)))
2338 : {
2339 5664998 : base_reg = XEXP (src, 0);
2340 :
2341 5664998 : if (CONST_INT_P (XEXP (src, 1)))
2342 4887216 : offset = UINTVAL (XEXP (src, 1));
2343 777782 : else if (REG_P (XEXP (src, 1))
2344 777782 : && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2345 : {
2346 83943 : if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2347 83943 : && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2348 6906 : offset = reg_offset[REGNO (XEXP (src, 1))];
2349 : /* Maybe the first register is known to be a
2350 : constant. */
2351 77037 : else if (move2add_valid_value_p (REGNO (base_reg), mode)
2352 20939 : && reg_base_reg[REGNO (base_reg)] < 0
2353 77871 : && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2354 : {
2355 722 : offset = reg_offset[REGNO (base_reg)];
2356 722 : base_reg = XEXP (src, 1);
2357 : }
2358 : else
2359 76315 : goto invalidate;
2360 : }
2361 : else
2362 693839 : goto invalidate;
2363 :
2364 : break;
2365 : }
2366 :
2367 300996 : goto invalidate;
2368 :
2369 : case REG:
2370 : base_reg = src;
2371 : offset = 0;
2372 : break;
2373 :
2374 4305263 : case CONST_INT:
2375 : /* Start tracking the register as a constant. */
2376 4305263 : reg_base_reg[regno] = -1;
2377 4305263 : reg_symbol_ref[regno] = NULL_RTX;
2378 4305263 : reg_offset[regno] = INTVAL (SET_SRC (set));
2379 : /* We assign the same luid to all registers set to constants. */
2380 4305263 : reg_set_luid[regno] = move2add_last_label_luid + 1;
2381 4305263 : move2add_record_mode (dst);
2382 4305263 : return;
2383 :
2384 11554765 : default:
2385 11554765 : goto invalidate;
2386 : }
2387 :
2388 9532933 : base_regno = REGNO (base_reg);
2389 : /* If information about the base register is not valid, set it
2390 : up as a new base register, pretending its value is known
2391 : starting from the current insn. */
2392 9532933 : if (!move2add_valid_value_p (base_regno, mode))
2393 : {
2394 6974778 : reg_base_reg[base_regno] = base_regno;
2395 6974778 : reg_symbol_ref[base_regno] = NULL_RTX;
2396 6974778 : reg_offset[base_regno] = 0;
2397 6974778 : reg_set_luid[base_regno] = move2add_luid;
2398 6974778 : gcc_assert (GET_MODE (base_reg) == mode);
2399 6974778 : move2add_record_mode (base_reg);
2400 : }
2401 :
2402 : /* Copy base information from our base register. */
2403 9532933 : reg_set_luid[regno] = reg_set_luid[base_regno];
2404 9532933 : reg_base_reg[regno] = reg_base_reg[base_regno];
2405 9532933 : reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2406 :
2407 : /* Compute the sum of the offsets or constants. */
2408 9532933 : reg_offset[regno]
2409 9532933 : = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2410 :
2411 9532933 : move2add_record_mode (dst);
2412 9532933 : }
2413 : else
2414 : {
2415 555169 : invalidate:
2416 : /* Invalidate the contents of the register. */
2417 29832069 : move2add_record_mode (dst);
2418 29832069 : reg_mode[regno] = VOIDmode;
2419 : }
2420 : }
2421 :
2422 : namespace {
2423 :
2424 : const pass_data pass_data_postreload_cse =
2425 : {
2426 : RTL_PASS, /* type */
2427 : "postreload", /* name */
2428 : OPTGROUP_NONE, /* optinfo_flags */
2429 : TV_RELOAD_CSE_REGS, /* tv_id */
2430 : 0, /* properties_required */
2431 : 0, /* properties_provided */
2432 : 0, /* properties_destroyed */
2433 : 0, /* todo_flags_start */
2434 : TODO_df_finish, /* todo_flags_finish */
2435 : };
2436 :
2437 : class pass_postreload_cse : public rtl_opt_pass
2438 : {
2439 : public:
2440 288047 : pass_postreload_cse (gcc::context *ctxt)
2441 576094 : : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2442 : {}
2443 :
2444 : /* opt_pass methods: */
2445 1474422 : bool gate (function *) final override
2446 : {
2447 1474422 : return (optimize > 0 && reload_completed);
2448 : }
2449 :
2450 : unsigned int execute (function *) final override;
2451 :
2452 : }; // class pass_postreload_cse
2453 :
2454 : unsigned int
2455 1041492 : pass_postreload_cse::execute (function *fun)
2456 : {
2457 1041492 : if (!dbg_cnt (postreload_cse))
2458 : return 0;
2459 :
2460 : /* Do a very simple CSE pass over just the hard registers. */
2461 1041492 : reload_cse_regs (get_insns ());
2462 : /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2463 : Remove any EH edges associated with them. */
2464 1041492 : if (fun->can_throw_non_call_exceptions
2465 1041492 : && purge_all_dead_edges ())
2466 116 : cleanup_cfg (0);
2467 :
2468 : return 0;
2469 : }
2470 :
2471 : } // anon namespace
2472 :
2473 : rtl_opt_pass *
2474 288047 : make_pass_postreload_cse (gcc::context *ctxt)
2475 : {
2476 288047 : return new pass_postreload_cse (ctxt);
2477 : }
|