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 1050840 : reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
64 : {
65 1050840 : bool moves_converted;
66 1050840 : reload_cse_regs_1 ();
67 1050840 : reload_combine ();
68 1050840 : moves_converted = reload_cse_move2add (first);
69 1050840 : if (flag_expensive_optimizations)
70 : {
71 969969 : if (moves_converted)
72 9435 : reload_combine ();
73 969969 : reload_cse_regs_1 ();
74 : }
75 1050840 : }
76 :
77 : /* Try to simplify INSN. Return true if the CFG may have changed. */
78 : static bool
79 214971379 : reload_cse_simplify (rtx_insn *insn, rtx testreg)
80 : {
81 214971379 : rtx body = PATTERN (insn);
82 214971379 : basic_block insn_bb = BLOCK_FOR_INSN (insn);
83 214971379 : 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 214971379 : if (NO_FUNCTION_CSE && CALL_P (insn))
88 : return false;
89 :
90 : /* Remember if this insn has been sp += const_int. */
91 205860020 : rtx sp_set = set_for_reg_notes (insn);
92 205860020 : rtx sp_addend = NULL_RTX;
93 205860020 : if (sp_set
94 68822284 : && SET_DEST (sp_set) == stack_pointer_rtx
95 3335570 : && GET_CODE (SET_SRC (sp_set)) == PLUS
96 3305170 : && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
97 3305067 : && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
98 205860020 : sp_addend = XEXP (SET_SRC (sp_set), 1);
99 :
100 205860020 : if (GET_CODE (body) == SET)
101 : {
102 88975889 : 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 88975889 : count += reload_cse_simplify_set (body, insn);
110 :
111 88975889 : if (!count && cselib_redundant_set_p (body))
112 : {
113 232433 : if (check_for_inc_dec (insn))
114 232433 : delete_insn_and_edges (insn);
115 : /* We're done with this insn. */
116 232433 : goto done;
117 : }
118 :
119 88743456 : if (count > 0)
120 146242 : apply_change_group ();
121 : else
122 88597214 : reload_cse_simplify_operands (insn, testreg);
123 : }
124 116884131 : else if (GET_CODE (body) == PARALLEL)
125 : {
126 14188777 : int i;
127 14188777 : int count = 0;
128 14188777 : 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 14188777 : if (asm_noperands (body) >= 0)
134 : {
135 628839 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
136 : {
137 479804 : rtx part = XVECEXP (body, 0, i);
138 479804 : if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
139 203864 : 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 28376342 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
146 : {
147 28372352 : rtx part = XVECEXP (body, 0, i);
148 28372352 : if (GET_CODE (part) == SET)
149 : {
150 14082834 : if (! cselib_redundant_set_p (part))
151 : break;
152 4057 : if (REG_P (SET_DEST (part))
153 4057 : && REG_FUNCTION_VALUE_P (SET_DEST (part)))
154 : {
155 0 : if (value)
156 : break;
157 : value = SET_DEST (part);
158 : }
159 : }
160 14289518 : else if (GET_CODE (part) != CLOBBER && GET_CODE (part) != USE)
161 : break;
162 : }
163 :
164 14188777 : if (i < 0)
165 : {
166 3990 : if (check_for_inc_dec (insn))
167 3990 : delete_insn_and_edges (insn);
168 : /* We're done with this insn. */
169 3990 : goto done;
170 : }
171 :
172 : /* It's not a no-op, but we can try to simplify it. */
173 43341465 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
174 29156678 : if (GET_CODE (XVECEXP (body, 0, i)) == SET)
175 14871098 : count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
176 :
177 14184787 : if (count > 0)
178 5704 : apply_change_group ();
179 : else
180 14179083 : 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 205623597 : if (sp_addend
186 3305067 : && SET_DEST (sp_set) == stack_pointer_rtx
187 3305067 : && REG_P (SET_SRC (sp_set)))
188 3069 : set_dst_reg_note (insn, REG_EQUAL,
189 3069 : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
190 : sp_addend), stack_pointer_rtx);
191 :
192 205620528 : done:
193 411716549 : 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 2020809 : reload_cse_regs_1 (void)
215 : {
216 2020809 : bool cfg_changed = false;
217 2020809 : basic_block bb;
218 2020809 : rtx_insn *insn;
219 2020809 : rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
220 :
221 2020809 : cselib_init (CSELIB_RECORD_MEMORY);
222 2020809 : init_alias_analysis ();
223 :
224 23429968 : 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 21409159 : rtx_insn *implicit_set;
230 :
231 21409159 : implicit_set = NULL;
232 21409159 : if (EDGE_COUNT (bb->preds) <= 3)
233 : {
234 20868119 : edge e;
235 20868119 : edge_iterator ei;
236 20868119 : rtx src = NULL_RTX;
237 20868119 : rtx dest = NULL_RTX;
238 :
239 : /* Iterate over each incoming edge and see if they
240 : all have the same implicit set. */
241 20868249 : FOR_EACH_EDGE (e, ei, bb->preds)
242 : {
243 : /* Skip the entry/exit block. */
244 20868119 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
245 : break;
246 :
247 : /* Verify this block ends with a suitable condjump */
248 18847376 : rtx_insn *condjump = BB_END (e->src);
249 18847376 : 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 14703358 : rtx pat = pc_set (condjump);
256 14703358 : rtx i_t_e = SET_SRC (pat);
257 14703358 : gcc_assert (GET_CODE (i_t_e) == IF_THEN_ELSE);
258 14703358 : rtx cond = XEXP (i_t_e, 0);
259 :
260 14703358 : if ((((e->flags & EDGE_FALLTHRU) != 0)
261 14703358 : == (XEXP (i_t_e, 1) == pc_rtx))
262 14703358 : ? GET_CODE (cond) == EQ
263 9071806 : : GET_CODE (cond) == NE)
264 : {
265 : /* If this is the first time through record
266 : the source and destination. */
267 5711866 : if (!dest)
268 : {
269 5711866 : dest = XEXP (cond, 0);
270 5711866 : 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 5711866 : if (!REG_P (dest)
286 5711842 : || !(REG_P (src) || CONST_INT_P (src))
287 5711842 : || GET_MODE_CLASS (GET_MODE (dest)) != MODE_INT
288 130 : || reg_set_p (dest, condjump)
289 5711996 : || 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 20868119 : if (dest && ei_end_p (ei))
303 130 : implicit_set = make_insn_raw (gen_rtx_SET (dest, src));
304 : }
305 :
306 281054186 : FOR_BB_INSNS (bb, insn)
307 : {
308 259645027 : 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 214971379 : if (implicit_set)
316 : {
317 130 : cselib_process_insn (implicit_set);
318 130 : implicit_set = NULL;
319 : }
320 214971379 : cfg_changed |= reload_cse_simplify (insn, testreg);
321 : }
322 :
323 259645027 : cselib_process_insn (insn);
324 : }
325 : }
326 :
327 : /* Clean up. */
328 2020809 : end_alias_analysis ();
329 2020809 : cselib_finish ();
330 2020809 : if (cfg_changed)
331 81 : cleanup_cfg (0);
332 2020809 : }
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 103846987 : reload_cse_simplify_set (rtx set, rtx_insn *insn)
342 : {
343 103846987 : int did_change = 0;
344 103846987 : int dreg;
345 103846987 : rtx src;
346 103846987 : reg_class_t dclass;
347 103846987 : int old_cost;
348 103846987 : cselib_val *val;
349 103846987 : struct elt_loc_list *l;
350 103846987 : enum rtx_code extend_op = UNKNOWN;
351 103846987 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
352 :
353 103846987 : dreg = true_regnum (SET_DEST (set));
354 103846987 : if (dreg < 0)
355 : return 0;
356 :
357 70094094 : src = SET_SRC (set);
358 70094094 : if (side_effects_p (src) || true_regnum (src) >= 0)
359 11066596 : return 0;
360 :
361 59027498 : 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 59027498 : 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 59027498 : val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
373 59027498 : if (! val)
374 : return 0;
375 :
376 : /* If memory loads are cheaper than register copies, don't change them. */
377 5692082 : if (MEM_P (src))
378 653530 : old_cost = memory_move_cost (GET_MODE (src), dclass, true);
379 5038552 : 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 5038552 : old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
384 :
385 11359511 : for (l = val->locs; l; l = l->next)
386 : {
387 5667429 : rtx this_rtx = l->loc;
388 5667429 : int this_cost;
389 :
390 5667429 : if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx))
391 : {
392 1931710 : 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 1931710 : this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
418 : }
419 3735719 : else if (REG_P (this_rtx))
420 : {
421 800103 : 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 800103 : this_cost = register_move_cost (GET_MODE (this_rtx),
428 800103 : REGNO_REG_CLASS (REGNO (this_rtx)),
429 : dclass);
430 : }
431 : else
432 2935616 : continue;
433 :
434 : /* If equal costs, prefer registers over anything else. That
435 : tends to lead to smaller instructions on some machines. */
436 2731813 : if (this_cost < old_cost
437 2580454 : || (this_cost == old_cost
438 1939309 : && REG_P (this_rtx)
439 13873 : && !REG_P (SET_SRC (set))))
440 : {
441 152325 : 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 152325 : validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
451 152325 : 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 102776297 : reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
471 : {
472 102776297 : int i, j;
473 :
474 : /* For each operand, all registers that are equivalent to it. */
475 102776297 : HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
476 :
477 102776297 : const char *constraints[MAX_RECOG_OPERANDS];
478 :
479 : /* Vector recording how bad an alternative is. */
480 102776297 : int *alternative_reject;
481 : /* Vector recording how many registers can be introduced by choosing
482 : this alternative. */
483 102776297 : 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 102776297 : int *op_alt_regno[MAX_RECOG_OPERANDS];
488 : /* Array of alternatives, sorted in order of decreasing desirability. */
489 102776297 : int *alternative_order;
490 :
491 102776297 : extract_constrain_insn (insn);
492 :
493 102776297 : if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
494 : return 0;
495 :
496 88807378 : alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
497 88807378 : alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
498 88807378 : alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
499 88807378 : memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
500 88807378 : memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
501 :
502 : /* For each operand, find out which regs are equivalent. */
503 287094963 : 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 198287585 : 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 198287585 : if (LABEL_P (recog_data.operand[i])
516 198274467 : || (NOTE_P (recog_data.operand[i])
517 116 : && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
518 198274351 : || (CONSTANT_P (recog_data.operand[i])
519 33828405 : && recog_data.operand_mode[i] == VOIDmode))
520 596122 : continue;
521 :
522 197691463 : op = recog_data.operand[i];
523 197691463 : 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 197691463 : if (side_effects_p (op))
571 4554031 : continue;
572 193137432 : v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
573 193137432 : if (! v)
574 127923073 : continue;
575 :
576 192447193 : for (l = v->locs; l; l = l->next)
577 127232834 : if (REG_P (l->loc))
578 67860759 : SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
579 : }
580 :
581 88807378 : alternative_mask preferred = get_preferred_alternatives (insn);
582 287094963 : for (i = 0; i < recog_data.n_operands; i++)
583 : {
584 198287585 : machine_mode mode;
585 198287585 : int regno;
586 198287585 : const char *p;
587 :
588 198287585 : op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
589 2947801658 : for (j = 0; j < recog_data.n_alternatives; j++)
590 2749514073 : op_alt_regno[i][j] = -1;
591 :
592 198287585 : p = constraints[i] = recog_data.constraints[i];
593 198287585 : mode = recog_data.operand_mode[i];
594 :
595 : /* Add the reject values for each alternative given by the constraints
596 : for this operand. */
597 198287585 : j = 0;
598 7922381615 : while (*p != '\0')
599 : {
600 7724094030 : char c = *p++;
601 7724094030 : if (c == ',')
602 2541701036 : j++;
603 5182392994 : else if (c == '?')
604 621509222 : alternative_reject[j] += 3;
605 4560883772 : else if (c == '!')
606 18310137 : 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 198287585 : regno = true_regnum (recog_data.operand[i]);
612 198287585 : if (regno >= 0
613 79133545 : || constraints[i][0] == '='
614 59493935 : || constraints[i][0] == '+')
615 138908561 : continue;
616 :
617 5522249232 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
618 : {
619 5462870208 : enum reg_class rclass = NO_REGS;
620 :
621 5462870208 : if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
622 5462125262 : continue;
623 :
624 744946 : 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 744946 : j = 0;
630 744946 : p = constraints[i];
631 40728060 : for (;;)
632 : {
633 40728060 : char c = *p;
634 :
635 40728060 : switch (c)
636 : {
637 189412 : case 'g':
638 189412 : rclass = reg_class_subunion[rclass][GENERAL_REGS];
639 189412 : break;
640 :
641 25784574 : default:
642 25784574 : rclass
643 25784574 : = (reg_class_subunion
644 25784574 : [rclass]
645 25784574 : [reg_class_for_constraint (lookup_constraint (p))]);
646 25784574 : break;
647 :
648 14754074 : 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 14754074 : if (op_alt_regno[i][j] == -1
654 14684605 : && TEST_BIT (preferred, j)
655 10007356 : && reg_fits_class_p (testreg, rclass, 0, mode)
656 17194660 : && (!CONST_INT_P (recog_data.operand[i])
657 2304974 : || (set_src_cost (recog_data.operand[i], mode,
658 : optimize_bb_for_speed_p
659 2304974 : (BLOCK_FOR_INSN (insn)))
660 2304974 : > set_src_cost (testreg, mode,
661 : optimize_bb_for_speed_p
662 2304974 : (BLOCK_FOR_INSN (insn))))))
663 : {
664 136284 : alternative_nregs[j]++;
665 136284 : op_alt_regno[i][j] = regno;
666 : }
667 14754074 : j++;
668 14754074 : rclass = NO_REGS;
669 14754074 : break;
670 : }
671 40728060 : p += CONSTRAINT_LEN (c, p);
672 :
673 40728060 : 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 88807378 : alternative_order[0] = 0;
682 88807378 : 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 1397716683 : for (i = j = 0; i < recog_data.n_alternatives; i++)
689 1308909305 : if (alternative_reject[i] <= alternative_reject[which_alternative])
690 763420811 : alternative_order[j++] = i;
691 88807378 : 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 763420811 : for (i = 0; i < recog_data.n_alternatives - 1; i++)
696 : {
697 674613433 : int best = i;
698 674613433 : int best_reject = alternative_reject[alternative_order[i]];
699 674613433 : int best_nregs = alternative_nregs[alternative_order[i]];
700 :
701 4694706118 : for (j = i + 1; j < recog_data.n_alternatives; j++)
702 : {
703 4020092685 : int this_reject = alternative_reject[alternative_order[j]];
704 4020092685 : int this_nregs = alternative_nregs[alternative_order[j]];
705 :
706 4020092685 : if (this_reject < best_reject
707 4013304291 : || (this_reject == best_reject && this_nregs > best_nregs))
708 : {
709 6867823 : best = j;
710 6867823 : best_reject = this_reject;
711 6867823 : best_nregs = this_nregs;
712 : }
713 : }
714 :
715 674613433 : 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 88807378 : j = alternative_order[0];
721 :
722 287094963 : for (i = 0; i < recog_data.n_operands; i++)
723 : {
724 198287585 : machine_mode mode = recog_data.operand_mode[i];
725 198287585 : if (op_alt_regno[i][j] == -1)
726 198236451 : continue;
727 :
728 51134 : validate_change (insn, recog_data.operand_loc[i],
729 : gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
730 : }
731 :
732 90170677 : for (i = recog_data.n_dups - 1; i >= 0; i--)
733 : {
734 1363299 : int op = recog_data.dup_num[i];
735 1363299 : machine_mode mode = recog_data.operand_mode[op];
736 :
737 1363299 : if (op_alt_regno[op][j] == -1)
738 1362938 : continue;
739 :
740 361 : validate_change (insn, recog_data.dup_loc[i],
741 : gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
742 : }
743 :
744 88807378 : 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 135524 : reload_combine_split_one_ruid (int *pruid, int split_ruid)
820 : {
821 135524 : if (*pruid > split_ruid)
822 5954 : (*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 481 : reload_combine_split_ruids (int split_ruid)
831 : {
832 481 : unsigned i;
833 :
834 481 : reload_combine_split_one_ruid (&reload_combine_ruid, split_ruid);
835 481 : reload_combine_split_one_ruid (&last_label_ruid, split_ruid);
836 481 : reload_combine_split_one_ruid (&last_jump_ruid, split_ruid);
837 :
838 44733 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
839 : {
840 44252 : int j, idx = reg_state[i].use_index;
841 44252 : reload_combine_split_one_ruid (®_state[i].use_ruid, split_ruid);
842 44252 : reload_combine_split_one_ruid (®_state[i].store_ruid, split_ruid);
843 44252 : reload_combine_split_one_ruid (®_state[i].real_store_ruid,
844 : split_ruid);
845 44252 : if (idx < 0)
846 18441 : continue;
847 27136 : for (j = idx; j < RELOAD_COMBINE_MAX_USES; j++)
848 : {
849 2403 : reload_combine_split_one_ruid (®_state[i].reg_use[j].ruid,
850 : split_ruid);
851 : }
852 : }
853 481 : }
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 4919 : reload_combine_purge_insn_uses (rtx_insn *insn)
861 : {
862 4919 : unsigned i;
863 :
864 457467 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
865 : {
866 452548 : int j, k, idx = reg_state[i].use_index;
867 452548 : if (idx < 0)
868 75567 : continue;
869 : j = k = RELOAD_COMBINE_MAX_USES;
870 412719 : while (j-- > idx)
871 : {
872 35738 : if (reg_state[i].reg_use[j].insn != insn)
873 : {
874 30303 : k--;
875 30303 : if (k != j)
876 3331 : reg_state[i].reg_use[k] = reg_state[i].reg_use[j];
877 : }
878 : }
879 376981 : reg_state[i].use_index = k;
880 : }
881 4919 : }
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 481 : reload_combine_purge_reg_uses_after_ruid (unsigned regno, int ruid)
888 : {
889 481 : int j, k, idx = reg_state[regno].use_index;
890 481 : if (idx < 0)
891 : return;
892 : j = k = RELOAD_COMBINE_MAX_USES;
893 1855 : while (j-- > idx)
894 : {
895 1374 : if (reg_state[regno].reg_use[j].ruid >= ruid)
896 : {
897 596 : k--;
898 596 : if (k != j)
899 452 : reg_state[regno].reg_use[k] = reg_state[regno].reg_use[j];
900 : }
901 : }
902 481 : 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 3900765 : reload_combine_closest_single_use (unsigned regno, int ruid_limit)
911 : {
912 3900765 : int i, best_ruid = 0;
913 3900765 : int use_idx = reg_state[regno].use_index;
914 3900765 : struct reg_use *retval;
915 :
916 3900765 : if (use_idx < 0)
917 : return NULL;
918 : retval = NULL;
919 3758645 : for (i = use_idx; i < RELOAD_COMBINE_MAX_USES; i++)
920 : {
921 2174271 : struct reg_use *use = reg_state[regno].reg_use + i;
922 2174271 : int this_ruid = use->ruid;
923 2174271 : if (this_ruid >= ruid_limit)
924 819098 : continue;
925 1355173 : if (this_ruid > best_ruid)
926 : {
927 : best_ruid = this_ruid;
928 : retval = use;
929 : }
930 354443 : else if (this_ruid == best_ruid)
931 2174271 : retval = NULL;
932 : }
933 1584374 : if (last_label_ruid >= best_ruid)
934 656812 : 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 647 : fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
946 : {
947 647 : rtx_insn *insn;
948 5895 : for (insn = from; insn != to; insn = NEXT_INSN (insn))
949 : {
950 5248 : rtx t;
951 :
952 5248 : if (!DEBUG_BIND_INSN_P (insn))
953 4049 : continue;
954 :
955 1199 : t = INSN_VAR_LOCATION_LOC (insn);
956 1199 : t = simplify_replace_rtx (t, reg, replacement);
957 1199 : validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0);
958 : }
959 647 : }
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 787283 : try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
967 : {
968 787283 : rtx_insn *use_insn = use->insn;
969 787283 : rtx mem = use->containing_mem;
970 787283 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
971 :
972 787283 : if (mem != NULL_RTX)
973 : {
974 13738 : addr_space_t as = MEM_ADDR_SPACE (mem);
975 13738 : rtx oldaddr = XEXP (mem, 0);
976 13738 : rtx newaddr = NULL_RTX;
977 13738 : int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed);
978 13738 : int new_cost;
979 :
980 13738 : newaddr = simplify_replace_rtx (oldaddr, reg, src);
981 13738 : if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as))
982 : {
983 4491 : XEXP (mem, 0) = newaddr;
984 4491 : new_cost = address_cost (newaddr, GET_MODE (mem), as, speed);
985 4491 : XEXP (mem, 0) = oldaddr;
986 4491 : if (new_cost <= old_cost
987 4491 : && validate_change (use_insn,
988 : &XEXP (mem, 0), newaddr, 0))
989 : return true;
990 : }
991 : }
992 : else
993 : {
994 773545 : rtx new_set = single_set (use_insn);
995 773545 : if (new_set
996 772579 : && REG_P (SET_DEST (new_set))
997 316721 : && GET_CODE (SET_SRC (new_set)) == PLUS
998 21899 : && REG_P (XEXP (SET_SRC (new_set), 0))
999 19589 : && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
1000 : {
1001 1608 : rtx new_src;
1002 1608 : machine_mode mode = GET_MODE (SET_DEST (new_set));
1003 1608 : int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
1004 :
1005 1608 : gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
1006 1608 : new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
1007 :
1008 1608 : if (set_src_cost (new_src, mode, speed) <= old_cost
1009 1608 : && 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 62574673 : reload_combine_recognize_const_pattern (rtx_insn *insn)
1025 : {
1026 62574673 : int from_ruid = reload_combine_ruid;
1027 62574673 : rtx set, pat, reg, src, addreg;
1028 62574673 : unsigned int regno;
1029 62574673 : struct reg_use *use;
1030 62574673 : bool must_move_add;
1031 62574673 : rtx_insn *add_moved_after_insn = NULL;
1032 62574673 : int add_moved_after_ruid = 0;
1033 62574673 : int clobbered_regno = -1;
1034 :
1035 62574673 : set = single_set (insn);
1036 62574673 : if (set == NULL_RTX)
1037 : return false;
1038 :
1039 58343412 : reg = SET_DEST (set);
1040 58343412 : src = SET_SRC (set);
1041 58343412 : if (!REG_P (reg)
1042 39794423 : || REG_NREGS (reg) != 1
1043 45487626 : || GET_MODE (reg) != Pmode
1044 81106724 : || reg == stack_pointer_rtx)
1045 : return false;
1046 :
1047 21055753 : 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 21055753 : if (GET_CODE (src) != PLUS
1054 4125205 : || !REG_P (XEXP (src, 0))
1055 3864037 : || !CONSTANT_P (XEXP (src, 1)))
1056 : return false;
1057 :
1058 3209694 : addreg = XEXP (src, 0);
1059 3209694 : must_move_add = rtx_equal_p (reg, addreg);
1060 :
1061 3209694 : pat = PATTERN (insn);
1062 3209694 : 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 841613 : gcc_assert (GET_CODE (PATTERN (insn)) == PARALLEL);
1069 841613 : if (XVECLEN (pat, 0) != 2 || XVECEXP (pat, 0, 0) != set
1070 841613 : || GET_CODE (XVECEXP (pat, 0, 1)) != CLOBBER
1071 841613 : || !REG_P (XEXP (XVECEXP (pat, 0, 1), 0)))
1072 : return false;
1073 841613 : clobbered_regno = REGNO (XEXP (XVECEXP (pat, 0, 1), 0));
1074 : }
1075 :
1076 3900765 : do
1077 : {
1078 3900765 : use = reload_combine_closest_single_use (regno, from_ruid);
1079 :
1080 3900765 : if (use)
1081 : /* Start the search for the next use from here. */
1082 902526 : from_ruid = use->ruid;
1083 :
1084 1257434 : if (use && GET_MODE (*use->usep) == Pmode)
1085 : {
1086 896378 : bool delete_add = false;
1087 896378 : rtx_insn *use_insn = use->insn;
1088 896378 : int use_ruid = use->ruid;
1089 :
1090 : /* Avoid moving the add insn past a jump. */
1091 896378 : 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 896080 : if (must_move_add && clobbered_regno >= 0
1097 126903 : && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1098 : break;
1099 :
1100 859039 : gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1101 : /* Avoid moving a use of ADDREG past a point where it is stored. */
1102 859039 : 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 787290 : if (must_move_add && reg_state[regno].store_ruid == use_ruid)
1108 : {
1109 28945 : if (use->containing_mem == NULL_RTX)
1110 : delete_add = true;
1111 : else
1112 : break;
1113 : }
1114 :
1115 787283 : if (try_replace_in_use (use, reg, src))
1116 : {
1117 4919 : reload_combine_purge_insn_uses (use_insn);
1118 4919 : reload_combine_note_use (&PATTERN (use_insn), use_insn,
1119 : use_ruid, NULL_RTX);
1120 :
1121 4919 : if (delete_add)
1122 : {
1123 49 : fixup_debug_insns (reg, src, insn, use_insn);
1124 49 : delete_insn (insn);
1125 49 : return true;
1126 : }
1127 4870 : if (must_move_add)
1128 : {
1129 860 : add_moved_after_insn = use_insn;
1130 860 : add_moved_after_ruid = use_ruid;
1131 : }
1132 4870 : continue;
1133 : }
1134 : }
1135 : /* If we get here, we couldn't handle this use. */
1136 3786751 : if (must_move_add)
1137 : break;
1138 : }
1139 2957917 : while (use);
1140 :
1141 3209645 : if (!must_move_add || add_moved_after_insn == NULL_RTX)
1142 : /* Process the add normally. */
1143 : return false;
1144 :
1145 481 : fixup_debug_insns (reg, src, insn, add_moved_after_insn);
1146 :
1147 481 : reorder_insns (insn, insn, add_moved_after_insn);
1148 481 : reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
1149 481 : reload_combine_split_ruids (add_moved_after_ruid - 1);
1150 481 : reload_combine_note_use (&PATTERN (insn), insn,
1151 : add_moved_after_ruid, NULL_RTX);
1152 481 : reg_state[regno].store_ruid = add_moved_after_ruid;
1153 :
1154 481 : 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 62574143 : reload_combine_recognize_pattern (rtx_insn *insn)
1163 : {
1164 62574143 : rtx set, reg, src;
1165 :
1166 62574143 : set = single_set (insn);
1167 62574143 : if (set == NULL_RTX)
1168 : return false;
1169 :
1170 58342882 : reg = SET_DEST (set);
1171 58342882 : src = SET_SRC (set);
1172 58342882 : if (!REG_P (reg) || REG_NREGS (reg) != 1)
1173 : return false;
1174 :
1175 39173564 : unsigned int regno = REGNO (reg);
1176 39173564 : machine_mode mode = GET_MODE (reg);
1177 :
1178 39173564 : if (reg_state[regno].use_index < 0
1179 39173564 : || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1180 : return false;
1181 :
1182 25166329 : for (int i = reg_state[regno].use_index;
1183 46068965 : i < RELOAD_COMBINE_MAX_USES; i++)
1184 : {
1185 25996250 : struct reg_use *use = reg_state[regno].reg_use + i;
1186 25996250 : if (GET_MODE (*use->usep) != mode)
1187 : return false;
1188 : /* Don't try to adjust (use (REGX)). */
1189 25170053 : if (GET_CODE (PATTERN (use->insn)) == USE
1190 25170053 : && &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 20072715 : if (GET_CODE (src) == PLUS
1209 2356734 : && reg_state[regno].all_offsets_match
1210 2098719 : && last_index_reg != -1
1211 2098719 : && REG_P (XEXP (src, 1))
1212 691250 : && rtx_equal_p (XEXP (src, 0), reg)
1213 500019 : && !rtx_equal_p (XEXP (src, 1), reg)
1214 20565469 : && last_label_ruid < reg_state[regno].use_ruid)
1215 : {
1216 460609 : rtx base = XEXP (src, 1);
1217 460609 : rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1218 460609 : rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1219 460609 : rtx index_reg = NULL_RTX;
1220 460609 : rtx reg_sum = NULL_RTX;
1221 460609 : 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 460609 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
1229 460609 : || 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 8784320 : for (i = first_index_reg; i <= last_index_reg; i++)
1242 : {
1243 8698541 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
1244 2991843 : && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1245 1702064 : && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1246 1687383 : && (crtl->abi->clobbers_full_reg_p (i)
1247 324485 : || df_regs_ever_live_p (i))
1248 1431058 : && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1249 1430024 : && !fixed_regs[i] && !global_regs[i]
1250 523320 : && hard_regno_nregs (i, GET_MODE (reg)) == 1
1251 8832926 : && targetm.hard_regno_scratch_ok (i))
1252 : {
1253 134385 : index_reg = gen_rtx_REG (GET_MODE (reg), i);
1254 134385 : reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1255 134385 : 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 460609 : if (reg_sum
1264 460609 : && prev_set
1265 368205 : && CONST_INT_P (SET_SRC (prev_set))
1266 8601 : && rtx_equal_p (SET_DEST (prev_set), reg)
1267 460609 : && (reg_state[REGNO (base)].store_ruid
1268 3501 : <= reg_state[regno].use_ruid))
1269 : {
1270 : /* Change destination register and, if necessary, the constant
1271 : value in PREV, the constant loading instruction. */
1272 3408 : validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
1273 3408 : 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 6880 : for (i = reg_state[regno].use_index;
1285 6880 : i < RELOAD_COMBINE_MAX_USES; i++)
1286 3472 : 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 3408 : 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 1060275 : reload_combine (void)
1328 : {
1329 1060275 : rtx_insn *insn, *prev;
1330 1060275 : basic_block bb;
1331 1060275 : unsigned int r;
1332 1060275 : int min_labelno, n_labels;
1333 1060275 : 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 1060275 : if (INDEX_REG_CLASS == NO_REGS)
1338 : last_index_reg = -1;
1339 1060275 : else if (first_index_reg == -1 && last_index_reg == 0)
1340 : {
1341 145727 : hard_reg_set_iterator hrsi1;
1342 4663264 : EXECUTE_IF_SET_IN_HARD_REG_SET
1343 : (reg_class_contents[INDEX_REG_CLASS], 0, r, hrsi1)
1344 : {
1345 4517537 : if (first_index_reg == -1)
1346 145727 : first_index_reg = r;
1347 :
1348 4517537 : 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 145727 : 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 1060275 : min_labelno = get_first_label_num ();
1365 1060275 : n_labels = max_label_num () - min_labelno;
1366 1060275 : label_live = XNEWVEC (HARD_REG_SET, n_labels);
1367 1060275 : CLEAR_HARD_REG_SET (ever_live_at_start);
1368 :
1369 12822569 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
1370 : {
1371 11762294 : insn = BB_HEAD (bb);
1372 11762294 : if (LABEL_P (insn))
1373 : {
1374 5486723 : HARD_REG_SET live;
1375 5486723 : bitmap live_in = df_get_live_in (bb);
1376 :
1377 10973446 : REG_SET_TO_HARD_REG_SET (live, live_in);
1378 5486723 : compute_use_by_pseudos (&live, live_in);
1379 5486723 : LABEL_LIVE (insn) = live;
1380 10973446 : ever_live_at_start |= live;
1381 : }
1382 : }
1383 :
1384 : /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
1385 1060275 : last_label_ruid = last_jump_ruid = reload_combine_ruid = 0;
1386 98605575 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1387 : {
1388 97545300 : reg_state[r].store_ruid = 0;
1389 97545300 : reg_state[r].real_store_ruid = 0;
1390 97545300 : if (fixed_regs[r])
1391 48296088 : reg_state[r].use_index = -1;
1392 : else
1393 49249212 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1394 : }
1395 :
1396 149223399 : for (insn = get_last_insn (); insn; insn = prev)
1397 : {
1398 148163124 : bool control_flow_insn;
1399 148163124 : rtx note;
1400 :
1401 148163124 : 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 148163124 : if (LABEL_P (insn))
1407 5493581 : last_label_ruid = reload_combine_ruid;
1408 142669543 : else if (BARRIER_P (insn))
1409 : {
1410 : /* Crossing a barrier resets all the use information. */
1411 295865736 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1412 292684384 : if (! fixed_regs[r])
1413 142922307 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1414 : }
1415 139488191 : 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 42481191 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1420 42024404 : if (! fixed_regs[r]
1421 19776351 : && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1422 677129 : reg_state[r].use_index = -1;
1423 :
1424 148163124 : if (! NONDEBUG_INSN_P (insn))
1425 85588451 : continue;
1426 :
1427 62574673 : reload_combine_ruid++;
1428 :
1429 62574673 : control_flow_insn = control_flow_insn_p (insn);
1430 62574673 : if (control_flow_insn)
1431 9032536 : last_jump_ruid = reload_combine_ruid;
1432 :
1433 62574673 : if (reload_combine_recognize_const_pattern (insn)
1434 62574673 : || reload_combine_recognize_pattern (insn))
1435 647 : continue;
1436 :
1437 62574026 : note_stores (insn, reload_combine_note_store, NULL);
1438 :
1439 62574026 : if (CALL_P (insn))
1440 : {
1441 4995919 : rtx link;
1442 4995919 : HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
1443 :
1444 4995919 : hard_reg_set_iterator hrsi2;
1445 412972384 : EXECUTE_IF_SET_IN_HARD_REG_SET (used_regs, 0, r, hrsi2)
1446 : {
1447 407976465 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1448 407976465 : reg_state[r].store_ruid = reload_combine_ruid;
1449 : }
1450 :
1451 15237652 : for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1452 10241733 : link = XEXP (link, 1))
1453 : {
1454 10241733 : rtx setuse = XEXP (link, 0);
1455 10241733 : rtx usage_rtx = XEXP (setuse, 0);
1456 :
1457 10241733 : if (GET_CODE (setuse) == USE && REG_P (usage_rtx))
1458 : {
1459 9257454 : unsigned int end_regno = END_REGNO (usage_rtx);
1460 18574821 : for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1461 9317367 : reg_state[i].use_index = -1;
1462 : }
1463 : }
1464 : }
1465 :
1466 62574026 : 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 9032536 : HARD_REG_SET *live;
1471 :
1472 10489060 : if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1473 9032619 : && JUMP_LABEL (insn))
1474 : {
1475 7576095 : if (ANY_RETURN_P (JUMP_LABEL (insn)))
1476 : live = NULL;
1477 : else
1478 7576095 : live = &LABEL_LIVE (JUMP_LABEL (insn));
1479 : }
1480 : else
1481 : live = &ever_live_at_start;
1482 :
1483 7576095 : if (live)
1484 : {
1485 9032536 : hard_reg_set_iterator hrsi3;
1486 54588529 : EXECUTE_IF_SET_IN_HARD_REG_SET (*live, 0, r, hrsi3)
1487 45555993 : reg_state[r].use_index = -1;
1488 : }
1489 : }
1490 :
1491 62574026 : reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1492 : NULL_RTX);
1493 :
1494 87002854 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1495 : {
1496 24428828 : 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 1060275 : 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 66912007 : reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1515 : {
1516 66912007 : int regno = 0;
1517 66912007 : int i;
1518 66912007 : machine_mode mode = GET_MODE (dst);
1519 :
1520 66912007 : if (GET_CODE (dst) == SUBREG)
1521 : {
1522 6320 : regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1523 3160 : GET_MODE (SUBREG_REG (dst)),
1524 3160 : SUBREG_BYTE (dst),
1525 : GET_MODE (dst));
1526 3160 : dst = SUBREG_REG (dst);
1527 : }
1528 :
1529 : /* Some targets do argument pushes without adding REG_INC notes. */
1530 :
1531 66912007 : if (MEM_P (dst))
1532 : {
1533 11075717 : dst = XEXP (dst, 0);
1534 11075717 : if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1535 11075717 : || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1536 9429448 : || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1537 : {
1538 1716453 : unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1539 3432906 : 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 1716453 : reg_state[i].use_index = -1;
1545 1716453 : reg_state[i].store_ruid = reload_combine_ruid;
1546 1716453 : reg_state[i].real_store_ruid = reload_combine_ruid;
1547 : }
1548 : }
1549 : else
1550 : return;
1551 : }
1552 :
1553 57552743 : if (!REG_P (dst))
1554 : return;
1555 48247682 : 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 48247682 : if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1561 48246563 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1562 : {
1563 8908 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1564 : {
1565 4454 : reg_state[i].use_index = -1;
1566 4454 : reg_state[i].store_ruid = reload_combine_ruid;
1567 4454 : reg_state[i].real_store_ruid = reload_combine_ruid;
1568 : }
1569 : }
1570 : else
1571 : {
1572 97115362 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1573 : {
1574 48872134 : reg_state[i].store_ruid = reload_combine_ruid;
1575 48872134 : if (GET_CODE (set) == SET)
1576 41288505 : reg_state[i].real_store_ruid = reload_combine_ruid;
1577 48872134 : 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 221872074 : reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1588 : {
1589 262519459 : rtx x = *xp;
1590 262519459 : enum rtx_code code = x->code;
1591 262519459 : const char *fmt;
1592 262519459 : int i, j;
1593 262519459 : rtx offset = const0_rtx; /* For the REG case below. */
1594 :
1595 262519459 : switch (code)
1596 : {
1597 59278756 : case SET:
1598 59278756 : if (REG_P (SET_DEST (x)))
1599 : {
1600 40647385 : reload_combine_note_use (&SET_SRC (x), insn, ruid, NULL_RTX);
1601 40647385 : return;
1602 : }
1603 : break;
1604 :
1605 664668 : case USE:
1606 : /* If this is the USE of a return value, we can't change it. */
1607 664668 : 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 563156 : rtx reg = XEXP (x, 0);
1611 563156 : unsigned int end_regno = END_REGNO (reg);
1612 1154907 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1613 591751 : reg_state[regno].use_index = -1;
1614 : return;
1615 : }
1616 : break;
1617 :
1618 7633757 : case CLOBBER:
1619 7633757 : if (REG_P (SET_DEST (x)))
1620 : {
1621 : /* No spurious CLOBBERs of pseudo registers may remain. */
1622 7582108 : gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1623 : return;
1624 : }
1625 : break;
1626 :
1627 23705159 : case PLUS:
1628 : /* We are interested in (plus (reg) (const_int)) . */
1629 23705159 : if (!REG_P (XEXP (x, 0))
1630 21304870 : || !CONST_INT_P (XEXP (x, 1)))
1631 : break;
1632 : offset = XEXP (x, 1);
1633 : x = XEXP (x, 0);
1634 : /* Fall through. */
1635 61295673 : case REG:
1636 61295673 : {
1637 61295673 : int regno = REGNO (x);
1638 61295673 : int use_index;
1639 61295673 : int nregs;
1640 :
1641 : /* No spurious USEs of pseudo registers may remain. */
1642 61295673 : gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1643 :
1644 61295673 : nregs = REG_NREGS (x);
1645 :
1646 : /* We can't substitute into multi-hard-reg uses. */
1647 61295673 : if (nregs > 1)
1648 : {
1649 1226475 : while (--nregs >= 0)
1650 817650 : 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 60886848 : 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 60885715 : use_index = --reg_state[regno].use_index;
1664 60885715 : if (use_index < 0)
1665 : return;
1666 :
1667 36704264 : 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 27840295 : reg_state[regno].offset = offset;
1672 27840295 : reg_state[regno].all_offsets_match = true;
1673 27840295 : reg_state[regno].use_ruid = ruid;
1674 : }
1675 : else
1676 : {
1677 8863969 : if (reg_state[regno].use_ruid > ruid)
1678 396 : reg_state[regno].use_ruid = ruid;
1679 :
1680 8863969 : if (! rtx_equal_p (offset, reg_state[regno].offset))
1681 3957218 : reg_state[regno].all_offsets_match = false;
1682 : }
1683 :
1684 36704264 : reg_state[regno].reg_use[use_index].insn = insn;
1685 36704264 : reg_state[regno].reg_use[use_index].ruid = ruid;
1686 36704264 : reg_state[regno].reg_use[use_index].containing_mem = containing_mem;
1687 36704264 : reg_state[regno].reg_use[use_index].usep = xp;
1688 36704264 : return;
1689 : }
1690 :
1691 : case MEM:
1692 152431137 : containing_mem = x;
1693 : break;
1694 :
1695 : default:
1696 : break;
1697 : }
1698 :
1699 : /* Recursively process the components of X. */
1700 152431137 : fmt = GET_RTX_FORMAT (code);
1701 389595821 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1702 : {
1703 237164684 : if (fmt[i] == 'e')
1704 138643552 : reload_combine_note_use (&XEXP (x, i), insn, ruid, containing_mem);
1705 98521132 : else if (fmt[i] == 'E')
1706 : {
1707 30647158 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1708 20648959 : 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 53330508 : move2add_record_mode (rtx reg)
1764 : {
1765 53330508 : int regno, nregs;
1766 53330508 : machine_mode mode = GET_MODE (reg);
1767 :
1768 53330508 : if (GET_CODE (reg) == SUBREG)
1769 : {
1770 3100 : regno = subreg_regno (reg);
1771 3100 : nregs = subreg_nregs (reg);
1772 : }
1773 53327408 : else if (REG_P (reg))
1774 : {
1775 53327408 : regno = REGNO (reg);
1776 53327408 : nregs = REG_NREGS (reg);
1777 : }
1778 : else
1779 0 : gcc_unreachable ();
1780 53988031 : for (int i = nregs - 1; i > 0; i--)
1781 657523 : reg_mode[regno + i] = BLKmode;
1782 53330508 : reg_mode[regno] = mode;
1783 53330508 : }
1784 :
1785 : /* Record that REG is being set to the sum of SYM and OFF. */
1786 :
1787 : static void
1788 2149477 : move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1789 : {
1790 2149477 : int regno = REGNO (reg);
1791 :
1792 2149477 : move2add_record_mode (reg);
1793 2149477 : reg_set_luid[regno] = move2add_luid;
1794 2149477 : reg_base_reg[regno] = -1;
1795 2149477 : reg_symbol_ref[regno] = sym;
1796 2149477 : reg_offset[regno] = INTVAL (off);
1797 2149477 : }
1798 :
1799 : /* Check if REGNO contains a valid value in MODE. */
1800 :
1801 : static bool
1802 216537377 : move2add_valid_value_p (int regno, scalar_int_mode mode)
1803 : {
1804 216537377 : if (reg_set_luid[regno] <= move2add_last_label_luid)
1805 : return false;
1806 :
1807 21988496 : if (mode != reg_mode[regno])
1808 : {
1809 11784671 : scalar_int_mode old_mode;
1810 11784671 : if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1811 7430688 : || !MODES_OK_FOR_MOVE2ADD (mode, old_mode)
1812 536768 : || !REG_CAN_CHANGE_MODE_P (regno, old_mode, mode))
1813 11247903 : 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 536768 : poly_int64 s_off = subreg_lowpart_offset (mode, old_mode);
1819 536768 : s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1820 536768 : 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 10791586 : for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1829 55066 : 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 151828 : move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1843 : rtx_insn *insn)
1844 : {
1845 151828 : rtx set = single_set (insn);
1846 151828 : rtx src = SET_SRC (set);
1847 151828 : int regno = REGNO (reg);
1848 151828 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1849 151828 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1850 151828 : 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 151828 : 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 26183 : if (INTVAL (off) == reg_offset [regno])
1865 24043 : changed = validate_change (insn, &SET_SRC (set), reg, 0);
1866 : }
1867 : else
1868 : {
1869 125645 : struct full_rtx_costs oldcst, newcst;
1870 125645 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1871 :
1872 125645 : get_full_set_rtx_cost (set, &oldcst);
1873 125645 : SET_SRC (set) = tem;
1874 125645 : get_full_set_rtx_cost (set, &newcst);
1875 125645 : SET_SRC (set) = src;
1876 :
1877 125645 : if (costs_lt_p (&newcst, &oldcst, speed)
1878 125645 : && have_add2_insn (reg, new_src))
1879 3687 : changed = validate_change (insn, &SET_SRC (set), tem, 0);
1880 121958 : else if (sym == NULL_RTX && mode != BImode)
1881 : {
1882 120530 : scalar_int_mode narrow_mode;
1883 404104 : FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1884 : {
1885 283574 : if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1886 283574 : && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1887 211372 : == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1888 : {
1889 92956 : rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1890 92956 : rtx narrow_src = gen_int_mode (INTVAL (off),
1891 : narrow_mode);
1892 92956 : rtx new_set
1893 92956 : = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1894 : narrow_reg),
1895 : narrow_src);
1896 92956 : 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 92956 : rtx *setloc = GET_CODE (PATTERN (insn)) == PARALLEL
1902 92956 : ? &XVECEXP (PATTERN (insn), 0, 0) : &PATTERN (insn);
1903 92956 : 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 151828 : move2add_record_sym_value (reg, sym, off);
1914 151828 : 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 1916738 : move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1929 : rtx_insn *insn)
1930 : {
1931 1916738 : rtx set = single_set (insn);
1932 1916738 : rtx src = SET_SRC (set);
1933 1916738 : int regno = REGNO (reg);
1934 1916738 : int min_regno = 0;
1935 1916738 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1936 1916738 : int i;
1937 1916738 : bool changed = false;
1938 1916738 : struct full_rtx_costs oldcst, newcst, mincst;
1939 1916738 : rtx plus_expr;
1940 :
1941 1916738 : init_costs_to_max (&mincst);
1942 1916738 : get_full_set_rtx_cost (set, &oldcst);
1943 :
1944 1916738 : plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1945 1916738 : SET_SRC (set) = plus_expr;
1946 :
1947 178256215 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1948 176339483 : if (move2add_valid_value_p (i, mode)
1949 3824570 : && reg_base_reg[i] < 0
1950 1517997 : && reg_symbol_ref[i] != NULL_RTX
1951 177372334 : && rtx_equal_p (sym, reg_symbol_ref[i]))
1952 : {
1953 38470 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1954 19235 : 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 19235 : 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 19229 : XEXP (plus_expr, 1) = new_src;
1970 19229 : get_full_set_rtx_cost (set, &newcst);
1971 :
1972 19229 : if (costs_lt_p (&newcst, &mincst, speed))
1973 : {
1974 18675 : mincst = newcst;
1975 18675 : min_regno = i;
1976 : }
1977 : }
1978 : }
1979 1916738 : SET_SRC (set) = src;
1980 :
1981 1916738 : 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 1916738 : changed = true;
1994 : }
1995 1916738 : reg_set_luid[regno] = move2add_luid;
1996 1916738 : move2add_record_sym_value (reg, sym, off);
1997 1916738 : return changed;
1998 : }
1999 :
2000 : /* Perform any invalidations necessary for INSN. */
2001 :
2002 : static void
2003 107184236 : reload_cse_move2add_invalidate (rtx_insn *insn)
2004 : {
2005 129972251 : for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
2006 : {
2007 22788015 : 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 107184236 : subrtx_var_iterator::array_type array;
2022 546098123 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
2023 : {
2024 438913887 : rtx mem = *iter;
2025 438913887 : if (mem
2026 438913887 : && MEM_P (mem)
2027 27986000 : && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
2028 : {
2029 1676349 : if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
2030 1676349 : reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
2031 : }
2032 : }
2033 :
2034 107184236 : 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 107184236 : if (any_condjump_p (insn))
2039 : {
2040 4833201 : rtx cnd = fis_get_condition (insn);
2041 :
2042 4833201 : if (cnd != NULL_RTX
2043 4324159 : && GET_CODE (cnd) == NE
2044 1941365 : && REG_P (XEXP (cnd, 0))
2045 1295032 : && !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 1295032 : && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2051 1295031 : && REG_NREGS (XEXP (cnd, 0)) == 1
2052 6128232 : && CONST_INT_P (XEXP (cnd, 1)))
2053 : {
2054 873750 : rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2055 873750 : 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 107184236 : if (CALL_P (insn))
2062 : {
2063 4694032 : function_abi callee_abi = insn_callee_abi (insn);
2064 436544976 : for (int i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2065 431850944 : if (reg_mode[i] != VOIDmode
2066 22046797 : && reg_mode[i] != BLKmode
2067 453340726 : && callee_abi.clobbers_reg_p (reg_mode[i], i))
2068 : /* Reset the information about this register. */
2069 8193927 : reg_mode[i] = VOIDmode;
2070 : }
2071 107184236 : }
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 1050840 : reload_cse_move2add (rtx_insn *first)
2077 : {
2078 1050840 : int i;
2079 1050840 : rtx_insn *insn;
2080 1050840 : bool changed = false;
2081 :
2082 97728120 : for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2083 : {
2084 96677280 : reg_set_luid[i] = 0;
2085 96677280 : reg_offset[i] = 0;
2086 96677280 : reg_base_reg[i] = 0;
2087 96677280 : reg_symbol_ref[i] = NULL_RTX;
2088 96677280 : reg_mode[i] = VOIDmode;
2089 : }
2090 :
2091 1050840 : move2add_last_label_luid = 0;
2092 1050840 : move2add_luid = 2;
2093 138401547 : for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
2094 : {
2095 137350707 : rtx set;
2096 :
2097 137350707 : if (LABEL_P (insn))
2098 : {
2099 5152888 : 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 5152888 : move2add_luid++;
2104 142503595 : continue;
2105 : }
2106 132197819 : if (! INSN_P (insn))
2107 22945017 : continue;
2108 109252802 : set = single_set (insn);
2109 : /* For simplicity, we only perform this optimization on
2110 : single-sets. */
2111 109252802 : scalar_int_mode mode;
2112 109252802 : if (set
2113 54676279 : && REG_P (SET_DEST (set))
2114 146573524 : && is_a <scalar_int_mode> (GET_MODE (SET_DEST (set)), &mode))
2115 : {
2116 27672698 : rtx reg = SET_DEST (set);
2117 27672698 : int regno = REGNO (reg);
2118 27672698 : 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 27672698 : if (move2add_valid_value_p (regno, mode)
2123 27672698 : && 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 3890478 : if (CONST_INT_P (src)
2139 334870 : && reg_base_reg[regno] < 0
2140 152640 : && reg_symbol_ref[regno] == NULL_RTX)
2141 : {
2142 150088 : changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
2143 : src, insn);
2144 150088 : 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 3740390 : else if (REG_P (src)
2158 471381 : && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
2159 121563 : && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
2160 3861953 : && move2add_valid_value_p (REGNO (src), mode))
2161 : {
2162 91687 : rtx_insn *next = next_nonnote_nondebug_insn (insn);
2163 91687 : rtx set = NULL_RTX;
2164 91687 : if (next)
2165 91676 : set = single_set (next);
2166 91676 : if (set
2167 70917 : && SET_DEST (set) == reg
2168 7242 : && GET_CODE (SET_SRC (set)) == PLUS
2169 674 : && XEXP (SET_SRC (set), 0) == reg
2170 669 : && CONST_INT_P (XEXP (SET_SRC (set), 1)))
2171 : {
2172 413 : rtx src3 = XEXP (SET_SRC (set), 1);
2173 413 : unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
2174 413 : HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
2175 413 : HOST_WIDE_INT regno_offset = reg_offset[regno];
2176 413 : rtx new_src =
2177 826 : gen_int_mode (added_offset
2178 413 : + base_offset
2179 413 : - regno_offset,
2180 : mode);
2181 413 : bool success = false;
2182 413 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
2183 :
2184 413 : if (new_src == const0_rtx)
2185 : /* See above why we create (set (reg) (reg)) here. */
2186 43 : success
2187 43 : = validate_change (next, &SET_SRC (set), reg, 0);
2188 : else
2189 : {
2190 370 : rtx old_src = SET_SRC (set);
2191 370 : struct full_rtx_costs oldcst, newcst;
2192 370 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
2193 :
2194 370 : get_full_set_rtx_cost (set, &oldcst);
2195 370 : SET_SRC (set) = tem;
2196 370 : get_full_set_src_cost (tem, mode, &newcst);
2197 370 : SET_SRC (set) = old_src;
2198 370 : costs_add_n_insns (&oldcst, 1);
2199 :
2200 370 : rtx *setloc = GET_CODE (PATTERN (next)) == PARALLEL
2201 370 : ? &XVECEXP (PATTERN (next), 0, 0) : &PATTERN (next);
2202 370 : if (*setloc == set
2203 370 : && costs_lt_p (&newcst, &oldcst, speed)
2204 740 : && have_add2_insn (reg, new_src))
2205 : {
2206 370 : rtx newpat = gen_rtx_SET (reg, tem);
2207 370 : success
2208 370 : = validate_change (next, setloc, newpat, 0);
2209 : }
2210 : }
2211 413 : if (success)
2212 413 : delete_insn (insn);
2213 413 : changed |= success;
2214 413 : 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 413 : reload_cse_move2add_invalidate (insn);
2221 413 : move2add_record_mode (reg);
2222 413 : reg_offset[regno]
2223 413 : = trunc_int_for_mode (added_offset + base_offset,
2224 : mode);
2225 413 : continue;
2226 413 : }
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 27522197 : if ((GET_CODE (src) == SYMBOL_REF
2239 25665051 : || (GET_CODE (src) == CONST
2240 61575 : && GET_CODE (XEXP (src, 0)) == PLUS
2241 61352 : && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF
2242 61332 : && CONST_INT_P (XEXP (XEXP (src, 0), 1))))
2243 27583529 : && dbg_cnt (cse2_move2add))
2244 : {
2245 1918478 : rtx sym, off;
2246 :
2247 1918478 : if (GET_CODE (src) == SYMBOL_REF)
2248 : {
2249 1857146 : sym = src;
2250 1857146 : off = const0_rtx;
2251 : }
2252 : else
2253 : {
2254 61332 : sym = XEXP (XEXP (src, 0), 0);
2255 61332 : 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 1918478 : if (move2add_valid_value_p (regno, mode)
2261 196806 : && reg_base_reg[regno] < 0
2262 127547 : && reg_symbol_ref[regno] != NULL_RTX
2263 1970175 : && rtx_equal_p (sym, reg_symbol_ref[regno]))
2264 1740 : 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 1916738 : changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2270 :
2271 1918478 : continue;
2272 1918478 : }
2273 : }
2274 107183823 : reload_cse_move2add_invalidate (insn);
2275 : }
2276 1050840 : 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 61624371 : move2add_note_store (rtx dst, const_rtx set, void *data)
2286 : {
2287 61624371 : rtx_insn *insn = (rtx_insn *) data;
2288 61624371 : unsigned int regno = 0;
2289 61624371 : scalar_int_mode mode;
2290 :
2291 61624371 : if (GET_CODE (dst) == SUBREG)
2292 3100 : regno = subreg_regno (dst);
2293 61621271 : else if (REG_P (dst))
2294 44160746 : regno = REGNO (dst);
2295 : else
2296 61624371 : return;
2297 :
2298 44163846 : if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2299 16943649 : goto invalidate;
2300 :
2301 27220197 : if (GET_CODE (set) == SET)
2302 : {
2303 27089006 : rtx note, sym = NULL_RTX;
2304 27089006 : rtx off;
2305 :
2306 27089006 : note = find_reg_equal_equiv_note (insn);
2307 27089006 : if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2308 : {
2309 70632 : sym = XEXP (note, 0);
2310 70632 : off = const0_rtx;
2311 : }
2312 4229841 : else if (note && GET_CODE (XEXP (note, 0)) == CONST
2313 10508 : && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2314 10299 : && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2315 10279 : && 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 80911 : if (sym != NULL_RTX)
2322 : {
2323 80911 : move2add_record_sym_value (dst, sym, off);
2324 80911 : return;
2325 : }
2326 : }
2327 :
2328 27139286 : if (GET_CODE (set) == SET
2329 27008095 : && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2330 27007024 : && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2331 : {
2332 27003856 : rtx src = SET_SRC (set);
2333 27003856 : rtx base_reg;
2334 27003856 : unsigned HOST_WIDE_INT offset;
2335 27003856 : int base_regno;
2336 :
2337 27003856 : switch (GET_CODE (src))
2338 : {
2339 6052798 : case PLUS:
2340 6052798 : if (REG_P (XEXP (src, 0)))
2341 : {
2342 5757001 : base_reg = XEXP (src, 0);
2343 :
2344 5757001 : if (CONST_INT_P (XEXP (src, 1)))
2345 4965443 : offset = UINTVAL (XEXP (src, 1));
2346 791558 : else if (REG_P (XEXP (src, 1))
2347 791558 : && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2348 : {
2349 90301 : if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2350 90301 : && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2351 6973 : offset = reg_offset[REGNO (XEXP (src, 1))];
2352 : /* Maybe the first register is known to be a
2353 : constant. */
2354 83328 : else if (move2add_valid_value_p (REGNO (base_reg), mode)
2355 22354 : && reg_base_reg[REGNO (base_reg)] < 0
2356 84256 : && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2357 : {
2358 820 : offset = reg_offset[REGNO (base_reg)];
2359 820 : base_reg = XEXP (src, 1);
2360 : }
2361 : else
2362 82508 : goto invalidate;
2363 : }
2364 : else
2365 701257 : goto invalidate;
2366 :
2367 : break;
2368 : }
2369 :
2370 295797 : goto invalidate;
2371 :
2372 : case REG:
2373 : base_reg = src;
2374 : offset = 0;
2375 : break;
2376 :
2377 4414172 : case CONST_INT:
2378 : /* Start tracking the register as a constant. */
2379 4414172 : reg_base_reg[regno] = -1;
2380 4414172 : reg_symbol_ref[regno] = NULL_RTX;
2381 4414172 : reg_offset[regno] = INTVAL (SET_SRC (set));
2382 : /* We assign the same luid to all registers set to constants. */
2383 4414172 : reg_set_luid[regno] = move2add_last_label_luid + 1;
2384 4414172 : move2add_record_mode (dst);
2385 4414172 : return;
2386 :
2387 11792115 : default:
2388 11792115 : goto invalidate;
2389 : }
2390 :
2391 9718007 : 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 9718007 : if (!move2add_valid_value_p (base_regno, mode))
2396 : {
2397 7097683 : reg_base_reg[base_regno] = base_regno;
2398 7097683 : reg_symbol_ref[base_regno] = NULL_RTX;
2399 7097683 : reg_offset[base_regno] = 0;
2400 7097683 : reg_set_luid[base_regno] = move2add_luid;
2401 7097683 : gcc_assert (GET_MODE (base_reg) == mode);
2402 7097683 : move2add_record_mode (base_reg);
2403 : }
2404 :
2405 : /* Copy base information from our base register. */
2406 9718007 : reg_set_luid[regno] = reg_set_luid[base_regno];
2407 9718007 : reg_base_reg[regno] = reg_base_reg[base_regno];
2408 9718007 : reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2409 :
2410 : /* Compute the sum of the offsets or constants. */
2411 9718007 : reg_offset[regno]
2412 9718007 : = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2413 :
2414 9718007 : move2add_record_mode (dst);
2415 9718007 : }
2416 : else
2417 : {
2418 135430 : invalidate:
2419 : /* Invalidate the contents of the register. */
2420 29950756 : move2add_record_mode (dst);
2421 29950756 : 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 293828 : pass_postreload_cse (gcc::context *ctxt)
2444 587656 : : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2445 : {}
2446 :
2447 : /* opt_pass methods: */
2448 1493948 : bool gate (function *) final override
2449 : {
2450 1493948 : 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 1050840 : pass_postreload_cse::execute (function *fun)
2459 : {
2460 1050840 : if (!dbg_cnt (postreload_cse))
2461 : return 0;
2462 :
2463 : /* Do a very simple CSE pass over just the hard registers. */
2464 1050840 : reload_cse_regs (get_insns ());
2465 : /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2466 : Remove any EH edges associated with them. */
2467 1050840 : if (fun->can_throw_non_call_exceptions
2468 1050840 : && purge_all_dead_edges ())
2469 114 : cleanup_cfg (0);
2470 :
2471 : return 0;
2472 : }
2473 :
2474 : } // anon namespace
2475 :
2476 : rtl_opt_pass *
2477 293828 : make_pass_postreload_cse (gcc::context *ctxt)
2478 : {
2479 293828 : return new pass_postreload_cse (ctxt);
2480 : }
|