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 1043685 : reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
64 : {
65 1043685 : bool moves_converted;
66 1043685 : reload_cse_regs_1 ();
67 1043685 : reload_combine ();
68 1043685 : moves_converted = reload_cse_move2add (first);
69 1043685 : if (flag_expensive_optimizations)
70 : {
71 963943 : if (moves_converted)
72 8824 : reload_combine ();
73 963943 : reload_cse_regs_1 ();
74 : }
75 1043685 : }
76 :
77 : /* Try to simplify INSN. Return true if the CFG may have changed. */
78 : static bool
79 210650600 : reload_cse_simplify (rtx_insn *insn, rtx testreg)
80 : {
81 210650600 : rtx body = PATTERN (insn);
82 210650600 : basic_block insn_bb = BLOCK_FOR_INSN (insn);
83 210650600 : 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 210650600 : if (NO_FUNCTION_CSE && CALL_P (insn))
88 : return false;
89 :
90 : /* Remember if this insn has been sp += const_int. */
91 201674396 : rtx sp_set = set_for_reg_notes (insn);
92 201674396 : rtx sp_addend = NULL_RTX;
93 201674396 : if (sp_set
94 68119491 : && SET_DEST (sp_set) == stack_pointer_rtx
95 3323140 : && GET_CODE (SET_SRC (sp_set)) == PLUS
96 3292155 : && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
97 3292052 : && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
98 201674396 : sp_addend = XEXP (SET_SRC (sp_set), 1);
99 :
100 201674396 : if (GET_CODE (body) == SET)
101 : {
102 88329371 : 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 88329371 : count += reload_cse_simplify_set (body, insn);
110 :
111 88329371 : if (!count && cselib_redundant_set_p (body))
112 : {
113 227381 : if (check_for_inc_dec (insn))
114 227381 : delete_insn_and_edges (insn);
115 : /* We're done with this insn. */
116 227381 : goto done;
117 : }
118 :
119 88101990 : if (count > 0)
120 150542 : apply_change_group ();
121 : else
122 87951448 : reload_cse_simplify_operands (insn, testreg);
123 : }
124 113345025 : else if (GET_CODE (body) == PARALLEL)
125 : {
126 14003158 : int i;
127 14003158 : int count = 0;
128 14003158 : 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 14003158 : if (asm_noperands (body) >= 0)
134 : {
135 610702 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
136 : {
137 466132 : rtx part = XVECEXP (body, 0, i);
138 466132 : if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
139 199399 : 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 27996726 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
146 : {
147 27992792 : rtx part = XVECEXP (body, 0, i);
148 27992792 : if (GET_CODE (part) == SET)
149 : {
150 13897459 : if (! cselib_redundant_set_p (part))
151 : break;
152 4075 : if (REG_P (SET_DEST (part))
153 4075 : && REG_FUNCTION_VALUE_P (SET_DEST (part)))
154 : {
155 0 : if (value)
156 : break;
157 : value = SET_DEST (part);
158 : }
159 : }
160 14095333 : else if (GET_CODE (part) != CLOBBER && GET_CODE (part) != USE)
161 : break;
162 : }
163 :
164 14003158 : if (i < 0)
165 : {
166 3934 : if (check_for_inc_dec (insn))
167 3934 : delete_insn_and_edges (insn);
168 : /* We're done with this insn. */
169 3934 : goto done;
170 : }
171 :
172 : /* It's not a no-op, but we can try to simplify it. */
173 42731372 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
174 28732148 : if (GET_CODE (XVECEXP (body, 0, i)) == SET)
175 14640679 : count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
176 :
177 13999224 : if (count > 0)
178 5401 : apply_change_group ();
179 : else
180 13993823 : 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 201443081 : if (sp_addend
186 3292052 : && SET_DEST (sp_set) == stack_pointer_rtx
187 3292052 : && REG_P (SET_SRC (sp_set)))
188 3058 : set_dst_reg_note (insn, REG_EQUAL,
189 3058 : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
190 : sp_addend), stack_pointer_rtx);
191 :
192 201440023 : done:
193 403346033 : 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 2007628 : reload_cse_regs_1 (void)
215 : {
216 2007628 : bool cfg_changed = false;
217 2007628 : basic_block bb;
218 2007628 : rtx_insn *insn;
219 2007628 : rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
220 :
221 2007628 : cselib_init (CSELIB_RECORD_MEMORY);
222 2007628 : init_alias_analysis ();
223 :
224 23391439 : 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 21383811 : rtx_insn *implicit_set;
230 :
231 21383811 : implicit_set = NULL;
232 21383811 : if (EDGE_COUNT (bb->preds) <= 3)
233 : {
234 20838884 : edge e;
235 20838884 : edge_iterator ei;
236 20838884 : rtx src = NULL_RTX;
237 20838884 : rtx dest = NULL_RTX;
238 :
239 : /* Iterate over each incoming edge and see if they
240 : all have the same implicit set. */
241 20839034 : FOR_EACH_EDGE (e, ei, bb->preds)
242 : {
243 : /* Skip the entry/exit block. */
244 20838884 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
245 : break;
246 :
247 : /* Verify this block ends with a suitable condjump */
248 18831317 : rtx_insn *condjump = BB_END (e->src);
249 18831317 : 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 14694907 : rtx pat = pc_set (condjump);
256 14694907 : rtx i_t_e = SET_SRC (pat);
257 14694907 : gcc_assert (GET_CODE (i_t_e) == IF_THEN_ELSE);
258 14694907 : rtx cond = XEXP (i_t_e, 0);
259 :
260 14694907 : if ((((e->flags & EDGE_FALLTHRU) != 0)
261 14694907 : == (XEXP (i_t_e, 1) == pc_rtx))
262 14694907 : ? GET_CODE (cond) == EQ
263 9073759 : : GET_CODE (cond) == NE)
264 : {
265 : /* If this is the first time through record
266 : the source and destination. */
267 5709320 : if (!dest)
268 : {
269 5709320 : dest = XEXP (cond, 0);
270 5709320 : 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 5709320 : if (!REG_P (dest)
286 5709296 : || !(REG_P (src) || CONST_INT_P (src))
287 5709296 : || GET_MODE_CLASS (GET_MODE (dest)) != MODE_INT
288 150 : || reg_set_p (dest, condjump)
289 5709470 : || 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 20838884 : if (dest && ei_end_p (ei))
303 150 : implicit_set = make_insn_raw (gen_rtx_SET (dest, src));
304 : }
305 :
306 276605439 : FOR_BB_INSNS (bb, insn)
307 : {
308 255221628 : 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 210650600 : if (implicit_set)
316 : {
317 150 : cselib_process_insn (implicit_set);
318 150 : implicit_set = NULL;
319 : }
320 210650600 : cfg_changed |= reload_cse_simplify (insn, testreg);
321 : }
322 :
323 255221628 : cselib_process_insn (insn);
324 : }
325 : }
326 :
327 : /* Clean up. */
328 2007628 : end_alias_analysis ();
329 2007628 : cselib_finish ();
330 2007628 : if (cfg_changed)
331 81 : cleanup_cfg (0);
332 2007628 : }
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 102970050 : reload_cse_simplify_set (rtx set, rtx_insn *insn)
342 : {
343 102970050 : int did_change = 0;
344 102970050 : int dreg;
345 102970050 : rtx src;
346 102970050 : reg_class_t dclass;
347 102970050 : int old_cost;
348 102970050 : cselib_val *val;
349 102970050 : struct elt_loc_list *l;
350 102970050 : enum rtx_code extend_op = UNKNOWN;
351 102970050 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
352 :
353 102970050 : dreg = true_regnum (SET_DEST (set));
354 102970050 : if (dreg < 0)
355 : return 0;
356 :
357 69324699 : src = SET_SRC (set);
358 69324699 : if (side_effects_p (src) || true_regnum (src) >= 0)
359 10918132 : return 0;
360 :
361 58406567 : 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 58406567 : 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 58406567 : val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
373 58406567 : if (! val)
374 : return 0;
375 :
376 : /* If memory loads are cheaper than register copies, don't change them. */
377 5629844 : if (MEM_P (src))
378 660377 : old_cost = memory_move_cost (GET_MODE (src), dclass, true);
379 4969467 : 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 4969467 : old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
384 :
385 11219263 : for (l = val->locs; l; l = l->next)
386 : {
387 5589419 : rtx this_rtx = l->loc;
388 5589419 : int this_cost;
389 :
390 5589419 : if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
391 : {
392 1872533 : 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 1872533 : this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
418 : }
419 3716886 : else if (REG_P (this_rtx))
420 : {
421 785960 : 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 785960 : this_cost = register_move_cost (GET_MODE (this_rtx),
428 785960 : REGNO_REG_CLASS (REGNO (this_rtx)),
429 : dclass);
430 : }
431 : else
432 2930926 : continue;
433 :
434 : /* If equal costs, prefer registers over anything else. That
435 : tends to lead to smaller instructions on some machines. */
436 2658493 : if (this_cost < old_cost
437 2503002 : || (this_cost == old_cost
438 1882494 : && REG_P (this_rtx)
439 15813 : && !REG_P (SET_SRC (set))))
440 : {
441 156264 : 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 156264 : validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
451 156264 : 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 101945271 : reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
471 : {
472 101945271 : int i, j;
473 :
474 : /* For each operand, all registers that are equivalent to it. */
475 101945271 : HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
476 :
477 101945271 : const char *constraints[MAX_RECOG_OPERANDS];
478 :
479 : /* Vector recording how bad an alternative is. */
480 101945271 : int *alternative_reject;
481 : /* Vector recording how many registers can be introduced by choosing
482 : this alternative. */
483 101945271 : 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 101945271 : int *op_alt_regno[MAX_RECOG_OPERANDS];
488 : /* Array of alternatives, sorted in order of decreasing desirability. */
489 101945271 : int *alternative_order;
490 :
491 101945271 : extract_constrain_insn (insn);
492 :
493 101945271 : if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
494 : return 0;
495 :
496 87957523 : alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
497 87957523 : alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
498 87957523 : alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
499 87957523 : memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
500 87957523 : memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
501 :
502 : /* For each operand, find out which regs are equivalent. */
503 284120759 : 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 196163236 : 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 196163236 : if (LABEL_P (recog_data.operand[i])
516 196147259 : || (NOTE_P (recog_data.operand[i])
517 100 : && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
518 196147159 : || (CONSTANT_P (recog_data.operand[i])
519 33350424 : && recog_data.operand_mode[i] == VOIDmode))
520 575550 : continue;
521 :
522 195587686 : op = recog_data.operand[i];
523 195587686 : 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 195587686 : if (side_effects_p (op))
571 4533631 : continue;
572 191054055 : v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
573 191054055 : if (! v)
574 126713309 : continue;
575 :
576 189278434 : for (l = v->locs; l; l = l->next)
577 124937688 : if (REG_P (l->loc))
578 66732696 : SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
579 : }
580 :
581 87957523 : alternative_mask preferred = get_preferred_alternatives (insn);
582 284120759 : for (i = 0; i < recog_data.n_operands; i++)
583 : {
584 196163236 : machine_mode mode;
585 196163236 : int regno;
586 196163236 : const char *p;
587 :
588 196163236 : op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
589 2871063439 : for (j = 0; j < recog_data.n_alternatives; j++)
590 2674900203 : op_alt_regno[i][j] = -1;
591 :
592 196163236 : p = constraints[i] = recog_data.constraints[i];
593 196163236 : mode = recog_data.operand_mode[i];
594 :
595 : /* Add the reject values for each alternative given by the constraints
596 : for this operand. */
597 196163236 : j = 0;
598 7755244328 : while (*p != '\0')
599 : {
600 7559081092 : char c = *p++;
601 7559081092 : if (c == ',')
602 2470061157 : j++;
603 5089019935 : else if (c == '?')
604 612638256 : alternative_reject[j] += 3;
605 4476381679 : else if (c == '!')
606 18430727 : 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 196163236 : regno = true_regnum (recog_data.operand[i]);
612 196163236 : if (regno >= 0
613 78447564 : || constraints[i][0] == '='
614 58927887 : || constraints[i][0] == '+')
615 137350159 : continue;
616 :
617 5469616161 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
618 : {
619 5410803084 : enum reg_class rclass = NO_REGS;
620 :
621 5410803084 : if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
622 5410075167 : continue;
623 :
624 727917 : 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 727917 : j = 0;
630 727917 : p = constraints[i];
631 39378478 : for (;;)
632 : {
633 39378478 : char c = *p;
634 :
635 39378478 : switch (c)
636 : {
637 187884 : case 'g':
638 187884 : rclass = reg_class_subunion[rclass][GENERAL_REGS];
639 187884 : break;
640 :
641 24914754 : default:
642 24914754 : rclass
643 24914754 : = (reg_class_subunion
644 24914754 : [rclass]
645 24914754 : [reg_class_for_constraint (lookup_constraint (p))]);
646 24914754 : break;
647 :
648 14275840 : 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 14275840 : if (op_alt_regno[i][j] == -1
654 14208927 : && TEST_BIT (preferred, j)
655 9714849 : && reg_fits_class_p (testreg, rclass, 0, mode)
656 16671314 : && (!CONST_INT_P (recog_data.operand[i])
657 2262846 : || (set_src_cost (recog_data.operand[i], mode,
658 : optimize_bb_for_speed_p
659 2262846 : (BLOCK_FOR_INSN (insn)))
660 2262846 : > set_src_cost (testreg, mode,
661 : optimize_bb_for_speed_p
662 2262846 : (BLOCK_FOR_INSN (insn))))))
663 : {
664 133304 : alternative_nregs[j]++;
665 133304 : op_alt_regno[i][j] = regno;
666 : }
667 14275840 : j++;
668 14275840 : rclass = NO_REGS;
669 14275840 : break;
670 : }
671 39378478 : p += CONSTRAINT_LEN (c, p);
672 :
673 39378478 : 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 87957523 : alternative_order[0] = 0;
682 87957523 : 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 1367452612 : for (i = j = 0; i < recog_data.n_alternatives; i++)
689 1279495089 : if (alternative_reject[i] <= alternative_reject[which_alternative])
690 741394820 : alternative_order[j++] = i;
691 87957523 : 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 741394820 : for (i = 0; i < recog_data.n_alternatives - 1; i++)
696 : {
697 653437297 : int best = i;
698 653437297 : int best_reject = alternative_reject[alternative_order[i]];
699 653437297 : int best_nregs = alternative_nregs[alternative_order[i]];
700 :
701 4526364406 : for (j = i + 1; j < recog_data.n_alternatives; j++)
702 : {
703 3872927109 : int this_reject = alternative_reject[alternative_order[j]];
704 3872927109 : int this_nregs = alternative_nregs[alternative_order[j]];
705 :
706 3872927109 : if (this_reject < best_reject
707 3866320067 : || (this_reject == best_reject && this_nregs > best_nregs))
708 : {
709 6684534 : best = j;
710 6684534 : best_reject = this_reject;
711 6684534 : best_nregs = this_nregs;
712 : }
713 : }
714 :
715 653437297 : 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 87957523 : j = alternative_order[0];
721 :
722 284120759 : for (i = 0; i < recog_data.n_operands; i++)
723 : {
724 196163236 : machine_mode mode = recog_data.operand_mode[i];
725 196163236 : if (op_alt_regno[i][j] == -1)
726 196113627 : continue;
727 :
728 49609 : validate_change (insn, recog_data.operand_loc[i],
729 : gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
730 : }
731 :
732 89252140 : for (i = recog_data.n_dups - 1; i >= 0; i--)
733 : {
734 1294617 : int op = recog_data.dup_num[i];
735 1294617 : machine_mode mode = recog_data.operand_mode[op];
736 :
737 1294617 : if (op_alt_regno[op][j] == -1)
738 1294203 : continue;
739 :
740 414 : validate_change (insn, recog_data.dup_loc[i],
741 : gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
742 : }
743 :
744 87957523 : 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 222252 : reload_combine_split_one_ruid (int *pruid, int split_ruid)
820 : {
821 222252 : if (*pruid > split_ruid)
822 9259 : (*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 786 : reload_combine_split_ruids (int split_ruid)
831 : {
832 786 : unsigned i;
833 :
834 786 : reload_combine_split_one_ruid (&reload_combine_ruid, split_ruid);
835 786 : reload_combine_split_one_ruid (&last_label_ruid, split_ruid);
836 786 : reload_combine_split_one_ruid (&last_jump_ruid, split_ruid);
837 :
838 73098 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
839 : {
840 72312 : int j, idx = reg_state[i].use_index;
841 72312 : reload_combine_split_one_ruid (®_state[i].use_ruid, split_ruid);
842 72312 : reload_combine_split_one_ruid (®_state[i].store_ruid, split_ruid);
843 72312 : reload_combine_split_one_ruid (®_state[i].real_store_ruid,
844 : split_ruid);
845 72312 : if (idx < 0)
846 26219 : continue;
847 49051 : for (j = idx; j < RELOAD_COMBINE_MAX_USES; j++)
848 : {
849 5236 : reload_combine_split_one_ruid (®_state[i].reg_use[j].ruid,
850 : split_ruid);
851 : }
852 : }
853 786 : }
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 5607 : reload_combine_purge_insn_uses (rtx_insn *insn)
861 : {
862 5607 : unsigned i;
863 :
864 521451 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
865 : {
866 515844 : int j, k, idx = reg_state[i].use_index;
867 515844 : if (idx < 0)
868 92036 : continue;
869 : j = k = RELOAD_COMBINE_MAX_USES;
870 467252 : while (j-- > idx)
871 : {
872 43444 : if (reg_state[i].reg_use[j].insn != insn)
873 : {
874 37218 : k--;
875 37218 : if (k != j)
876 3641 : reg_state[i].reg_use[k] = reg_state[i].reg_use[j];
877 : }
878 : }
879 423808 : reg_state[i].use_index = k;
880 : }
881 5607 : }
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 786 : reload_combine_purge_reg_uses_after_ruid (unsigned regno, int ruid)
888 : {
889 786 : int j, k, idx = reg_state[regno].use_index;
890 786 : if (idx < 0)
891 : return;
892 : j = k = RELOAD_COMBINE_MAX_USES;
893 3042 : while (j-- > idx)
894 : {
895 2256 : if (reg_state[regno].reg_use[j].ruid >= ruid)
896 : {
897 1319 : k--;
898 1319 : if (k != j)
899 527 : reg_state[regno].reg_use[k] = reg_state[regno].reg_use[j];
900 : }
901 : }
902 786 : 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 3812647 : reload_combine_closest_single_use (unsigned regno, int ruid_limit)
911 : {
912 3812647 : int i, best_ruid = 0;
913 3812647 : int use_idx = reg_state[regno].use_index;
914 3812647 : struct reg_use *retval;
915 :
916 3812647 : if (use_idx < 0)
917 : return NULL;
918 : retval = NULL;
919 3726605 : for (i = use_idx; i < RELOAD_COMBINE_MAX_USES; i++)
920 : {
921 2152457 : struct reg_use *use = reg_state[regno].reg_use + i;
922 2152457 : int this_ruid = use->ruid;
923 2152457 : if (this_ruid >= ruid_limit)
924 824941 : continue;
925 1327516 : if (this_ruid > best_ruid)
926 : {
927 : best_ruid = this_ruid;
928 : retval = use;
929 : }
930 342451 : else if (this_ruid == best_ruid)
931 2152457 : retval = NULL;
932 : }
933 1574148 : if (last_label_ruid >= best_ruid)
934 661585 : 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 921 : fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
946 : {
947 921 : rtx_insn *insn;
948 5330 : for (insn = from; insn != to; insn = NEXT_INSN (insn))
949 : {
950 4409 : rtx t;
951 :
952 4409 : if (!DEBUG_BIND_INSN_P (insn))
953 3972 : continue;
954 :
955 437 : t = INSN_VAR_LOCATION_LOC (insn);
956 437 : t = simplify_replace_rtx (t, reg, replacement);
957 437 : validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0);
958 : }
959 921 : }
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 788023 : try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
967 : {
968 788023 : rtx_insn *use_insn = use->insn;
969 788023 : rtx mem = use->containing_mem;
970 788023 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
971 :
972 788023 : if (mem != NULL_RTX)
973 : {
974 17517 : addr_space_t as = MEM_ADDR_SPACE (mem);
975 17517 : rtx oldaddr = XEXP (mem, 0);
976 17517 : rtx newaddr = NULL_RTX;
977 17517 : int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed);
978 17517 : int new_cost;
979 :
980 17517 : newaddr = simplify_replace_rtx (oldaddr, reg, src);
981 17517 : if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as))
982 : {
983 5199 : XEXP (mem, 0) = newaddr;
984 5199 : new_cost = address_cost (newaddr, GET_MODE (mem), as, speed);
985 5199 : XEXP (mem, 0) = oldaddr;
986 5199 : if (new_cost <= old_cost
987 5199 : && validate_change (use_insn,
988 : &XEXP (mem, 0), newaddr, 0))
989 : return true;
990 : }
991 : }
992 : else
993 : {
994 770506 : rtx new_set = single_set (use_insn);
995 770506 : if (new_set
996 769551 : && REG_P (SET_DEST (new_set))
997 321634 : && GET_CODE (SET_SRC (new_set)) == PLUS
998 20913 : && REG_P (XEXP (SET_SRC (new_set), 0))
999 18869 : && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
1000 : {
1001 1529 : rtx new_src;
1002 1529 : machine_mode mode = GET_MODE (SET_DEST (new_set));
1003 1529 : int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
1004 :
1005 1529 : gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
1006 1529 : new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
1007 :
1008 1529 : if (set_src_cost (new_src, mode, speed) <= old_cost
1009 1529 : && 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 61758141 : reload_combine_recognize_const_pattern (rtx_insn *insn)
1025 : {
1026 61758141 : int from_ruid = reload_combine_ruid;
1027 61758141 : rtx set, pat, reg, src, addreg;
1028 61758141 : unsigned int regno;
1029 61758141 : struct reg_use *use;
1030 61758141 : bool must_move_add;
1031 61758141 : rtx_insn *add_moved_after_insn = NULL;
1032 61758141 : int add_moved_after_ruid = 0;
1033 61758141 : int clobbered_regno = -1;
1034 :
1035 61758141 : set = single_set (insn);
1036 61758141 : if (set == NULL_RTX)
1037 : return false;
1038 :
1039 57620871 : reg = SET_DEST (set);
1040 57620871 : src = SET_SRC (set);
1041 57620871 : if (!REG_P (reg)
1042 39222005 : || REG_NREGS (reg) != 1
1043 44899119 : || GET_MODE (reg) != Pmode
1044 79874021 : || reg == stack_pointer_rtx)
1045 : return false;
1046 :
1047 20549601 : 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 20549601 : if (GET_CODE (src) != PLUS
1054 4039584 : || !REG_P (XEXP (src, 0))
1055 3768747 : || !CONSTANT_P (XEXP (src, 1)))
1056 : return false;
1057 :
1058 3117274 : addreg = XEXP (src, 0);
1059 3117274 : must_move_add = rtx_equal_p (reg, addreg);
1060 :
1061 3117274 : pat = PATTERN (insn);
1062 3117274 : 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 828870 : gcc_assert (GET_CODE (PATTERN (insn)) == PARALLEL);
1069 828870 : if (XVECLEN (pat, 0) != 2 || XVECEXP (pat, 0, 0) != set
1070 828870 : || GET_CODE (XVECEXP (pat, 0, 1)) != CLOBBER
1071 828870 : || !REG_P (XEXP (XVECEXP (pat, 0, 1), 0)))
1072 : return false;
1073 828870 : clobbered_regno = REGNO (XEXP (XVECEXP (pat, 0, 1), 0));
1074 : }
1075 :
1076 3812647 : do
1077 : {
1078 3812647 : use = reload_combine_closest_single_use (regno, from_ruid);
1079 :
1080 3812647 : if (use)
1081 : /* Start the search for the next use from here. */
1082 889999 : from_ruid = use->ruid;
1083 :
1084 1248789 : if (use && GET_MODE (*use->usep) == Pmode)
1085 : {
1086 884215 : bool delete_add = false;
1087 884215 : rtx_insn *use_insn = use->insn;
1088 884215 : int use_ruid = use->ruid;
1089 :
1090 : /* Avoid moving the add insn past a jump. */
1091 884215 : 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 883898 : if (must_move_add && clobbered_regno >= 0
1097 113015 : && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1098 : break;
1099 :
1100 857798 : gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1101 : /* Avoid moving a use of ADDREG past a point where it is stored. */
1102 857798 : 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 788029 : if (must_move_add && reg_state[regno].store_ruid == use_ruid)
1108 : {
1109 29776 : if (use->containing_mem == NULL_RTX)
1110 : delete_add = true;
1111 : else
1112 : break;
1113 : }
1114 :
1115 788023 : if (try_replace_in_use (use, reg, src))
1116 : {
1117 5607 : reload_combine_purge_insn_uses (use_insn);
1118 5607 : reload_combine_note_use (&PATTERN (use_insn), use_insn,
1119 : use_ruid, NULL_RTX);
1120 :
1121 5607 : if (delete_add)
1122 : {
1123 18 : fixup_debug_insns (reg, src, insn, use_insn);
1124 18 : delete_insn (insn);
1125 18 : return true;
1126 : }
1127 5589 : if (must_move_add)
1128 : {
1129 1353 : add_moved_after_insn = use_insn;
1130 1353 : add_moved_after_ruid = use_ruid;
1131 : }
1132 5589 : continue;
1133 : }
1134 : }
1135 : /* If we get here, we couldn't handle this use. */
1136 3710848 : if (must_move_add)
1137 : break;
1138 : }
1139 2885986 : while (use);
1140 :
1141 3117256 : if (!must_move_add || add_moved_after_insn == NULL_RTX)
1142 : /* Process the add normally. */
1143 : return false;
1144 :
1145 786 : fixup_debug_insns (reg, src, insn, add_moved_after_insn);
1146 :
1147 786 : reorder_insns (insn, insn, add_moved_after_insn);
1148 786 : reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
1149 786 : reload_combine_split_ruids (add_moved_after_ruid - 1);
1150 786 : reload_combine_note_use (&PATTERN (insn), insn,
1151 : add_moved_after_ruid, NULL_RTX);
1152 786 : reg_state[regno].store_ruid = add_moved_after_ruid;
1153 :
1154 786 : 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 61757337 : reload_combine_recognize_pattern (rtx_insn *insn)
1163 : {
1164 61757337 : rtx set, reg, src;
1165 :
1166 61757337 : set = single_set (insn);
1167 61757337 : if (set == NULL_RTX)
1168 : return false;
1169 :
1170 57620067 : reg = SET_DEST (set);
1171 57620067 : src = SET_SRC (set);
1172 57620067 : if (!REG_P (reg) || REG_NREGS (reg) != 1)
1173 : return false;
1174 :
1175 38599449 : unsigned int regno = REGNO (reg);
1176 38599449 : machine_mode mode = GET_MODE (reg);
1177 :
1178 38599449 : if (reg_state[regno].use_index < 0
1179 38599449 : || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1180 : return false;
1181 :
1182 24985671 : for (int i = reg_state[regno].use_index;
1183 45645525 : i < RELOAD_COMBINE_MAX_USES; i++)
1184 : {
1185 25746346 : struct reg_use *use = reg_state[regno].reg_use + i;
1186 25746346 : if (GET_MODE (*use->usep) != mode)
1187 : return false;
1188 : /* Don't try to adjust (use (REGX)). */
1189 24990012 : if (GET_CODE (PATTERN (use->insn)) == USE
1190 24990012 : && &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 19899179 : if (GET_CODE (src) == PLUS
1209 2393641 : && reg_state[regno].all_offsets_match
1210 2114933 : && last_index_reg != -1
1211 2114933 : && REG_P (XEXP (src, 1))
1212 699235 : && rtx_equal_p (XEXP (src, 0), reg)
1213 506127 : && !rtx_equal_p (XEXP (src, 1), reg)
1214 20398181 : && last_label_ruid < reg_state[regno].use_ruid)
1215 : {
1216 467630 : rtx base = XEXP (src, 1);
1217 467630 : rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1218 467630 : rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1219 467630 : rtx index_reg = NULL_RTX;
1220 467630 : rtx reg_sum = NULL_RTX;
1221 467630 : 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 467630 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
1229 467630 : || 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 8911311 : for (i = first_index_reg; i <= last_index_reg; i++)
1242 : {
1243 8821550 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
1244 3078169 : && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1245 1758632 : && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1246 1744106 : && (crtl->abi->clobbers_full_reg_p (i)
1247 336384 : || df_regs_ever_live_p (i))
1248 1485750 : && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1249 1484701 : && !fixed_regs[i] && !global_regs[i]
1250 537077 : && hard_regno_nregs (i, GET_MODE (reg)) == 1
1251 8954793 : && targetm.hard_regno_scratch_ok (i))
1252 : {
1253 133243 : index_reg = gen_rtx_REG (GET_MODE (reg), i);
1254 133243 : reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1255 133243 : 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 467630 : if (reg_sum
1264 467630 : && prev_set
1265 370988 : && CONST_INT_P (SET_SRC (prev_set))
1266 8385 : && rtx_equal_p (SET_DEST (prev_set), reg)
1267 467630 : && (reg_state[REGNO (base)].store_ruid
1268 2758 : <= reg_state[regno].use_ruid))
1269 : {
1270 : /* Change destination register and, if necessary, the constant
1271 : value in PREV, the constant loading instruction. */
1272 2669 : validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
1273 2669 : 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 5399 : for (i = reg_state[regno].use_index;
1285 5399 : i < RELOAD_COMBINE_MAX_USES; i++)
1286 2730 : 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 2669 : 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 1052509 : reload_combine (void)
1328 : {
1329 1052509 : rtx_insn *insn, *prev;
1330 1052509 : basic_block bb;
1331 1052509 : unsigned int r;
1332 1052509 : int min_labelno, n_labels;
1333 1052509 : 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 1052509 : if (INDEX_REG_CLASS == NO_REGS)
1338 : last_index_reg = -1;
1339 1052509 : else if (first_index_reg == -1 && last_index_reg == 0)
1340 : {
1341 13337223 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1342 13193812 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
1343 : {
1344 4445741 : if (first_index_reg == -1)
1345 143411 : first_index_reg = r;
1346 :
1347 4445741 : 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 143411 : 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 1052509 : min_labelno = get_first_label_num ();
1364 1052509 : n_labels = max_label_num () - min_labelno;
1365 1052509 : label_live = XNEWVEC (HARD_REG_SET, n_labels);
1366 1052509 : CLEAR_HARD_REG_SET (ever_live_at_start);
1367 :
1368 12735642 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
1369 : {
1370 11683133 : insn = BB_HEAD (bb);
1371 11683133 : if (LABEL_P (insn))
1372 : {
1373 5446494 : HARD_REG_SET live;
1374 5446494 : bitmap live_in = df_get_live_in (bb);
1375 :
1376 10892988 : REG_SET_TO_HARD_REG_SET (live, live_in);
1377 5446494 : compute_use_by_pseudos (&live, live_in);
1378 5446494 : LABEL_LIVE (insn) = live;
1379 10892988 : ever_live_at_start |= live;
1380 : }
1381 : }
1382 :
1383 : /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
1384 1052509 : last_label_ruid = last_jump_ruid = reload_combine_ruid = 0;
1385 97883337 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1386 : {
1387 96830828 : reg_state[r].store_ruid = 0;
1388 96830828 : reg_state[r].real_store_ruid = 0;
1389 96830828 : if (fixed_regs[r])
1390 47942642 : reg_state[r].use_index = -1;
1391 : else
1392 48888186 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1393 : }
1394 :
1395 145031392 : for (insn = get_last_insn (); insn; insn = prev)
1396 : {
1397 143978883 : bool control_flow_insn;
1398 143978883 : rtx note;
1399 :
1400 143978883 : 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 143978883 : if (LABEL_P (insn))
1406 5454902 : last_label_ruid = reload_combine_ruid;
1407 138523981 : else if (BARRIER_P (insn))
1408 : {
1409 : /* Crossing a barrier resets all the use information. */
1410 292279191 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1411 289136404 : if (! fixed_regs[r])
1412 141148962 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1413 : }
1414 135381194 : 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 42269430 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1419 41814920 : if (! fixed_regs[r]
1420 19671252 : && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1421 671033 : reg_state[r].use_index = -1;
1422 :
1423 143978883 : if (! NONDEBUG_INSN_P (insn))
1424 82220742 : continue;
1425 :
1426 61758141 : reload_combine_ruid++;
1427 :
1428 61758141 : control_flow_insn = control_flow_insn_p (insn);
1429 61758141 : if (control_flow_insn)
1430 8963270 : last_jump_ruid = reload_combine_ruid;
1431 :
1432 61758141 : if (reload_combine_recognize_const_pattern (insn)
1433 61758141 : || reload_combine_recognize_pattern (insn))
1434 921 : continue;
1435 :
1436 61757220 : note_stores (insn, reload_combine_note_store, NULL);
1437 :
1438 61757220 : if (CALL_P (insn))
1439 : {
1440 4889475 : rtx link;
1441 4889475 : HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
1442 :
1443 454721175 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1444 449831700 : if (TEST_HARD_REG_BIT (used_regs, r))
1445 : {
1446 398878378 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1447 398878378 : reg_state[r].store_ruid = reload_combine_ruid;
1448 : }
1449 :
1450 15260862 : for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1451 10371387 : link = XEXP (link, 1))
1452 : {
1453 10371387 : rtx setuse = XEXP (link, 0);
1454 10371387 : rtx usage_rtx = XEXP (setuse, 0);
1455 :
1456 10371387 : if (GET_CODE (setuse) == USE && REG_P (usage_rtx))
1457 : {
1458 8971391 : unsigned int end_regno = END_REGNO (usage_rtx);
1459 17997087 : for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1460 9025696 : reg_state[i].use_index = -1;
1461 : }
1462 : }
1463 : }
1464 :
1465 61757220 : 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 8963270 : HARD_REG_SET *live;
1470 :
1471 10387102 : if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1472 8963368 : && JUMP_LABEL (insn))
1473 : {
1474 7539536 : if (ANY_RETURN_P (JUMP_LABEL (insn)))
1475 : live = NULL;
1476 : else
1477 7539536 : live = &LABEL_LIVE (JUMP_LABEL (insn));
1478 : }
1479 : else
1480 : live = &ever_live_at_start;
1481 :
1482 8963270 : if (live)
1483 833584110 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1484 824620840 : if (TEST_HARD_REG_BIT (*live, r))
1485 45145767 : reg_state[r].use_index = -1;
1486 : }
1487 :
1488 61757220 : reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1489 : NULL_RTX);
1490 :
1491 85917352 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1492 : {
1493 24160132 : 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 1052509 : 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 66451525 : reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1512 : {
1513 66451525 : int regno = 0;
1514 66451525 : int i;
1515 66451525 : machine_mode mode = GET_MODE (dst);
1516 :
1517 66451525 : if (GET_CODE (dst) == SUBREG)
1518 : {
1519 7432 : regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1520 3716 : GET_MODE (SUBREG_REG (dst)),
1521 3716 : SUBREG_BYTE (dst),
1522 : GET_MODE (dst));
1523 3716 : dst = SUBREG_REG (dst);
1524 : }
1525 :
1526 : /* Some targets do argument pushes without adding REG_INC notes. */
1527 :
1528 66451525 : if (MEM_P (dst))
1529 : {
1530 10951433 : dst = XEXP (dst, 0);
1531 10951433 : if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1532 10951433 : || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1533 9309645 : || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1534 : {
1535 1710745 : unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1536 3421490 : 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 1710745 : reg_state[i].use_index = -1;
1542 1710745 : reg_state[i].store_ruid = reload_combine_ruid;
1543 1710745 : reg_state[i].real_store_ruid = reload_combine_ruid;
1544 : }
1545 : }
1546 : else
1547 : return;
1548 : }
1549 :
1550 57210837 : if (!REG_P (dst))
1551 : return;
1552 47946525 : 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 47946525 : if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1558 47945436 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1559 : {
1560 8688 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1561 : {
1562 4344 : reg_state[i].use_index = -1;
1563 4344 : reg_state[i].store_ruid = reload_combine_ruid;
1564 4344 : reg_state[i].real_store_ruid = reload_combine_ruid;
1565 : }
1566 : }
1567 : else
1568 : {
1569 96514139 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1570 : {
1571 48571958 : reg_state[i].store_ruid = reload_combine_ruid;
1572 48571958 : if (GET_CODE (set) == SET)
1573 40679146 : reg_state[i].real_store_ruid = reload_combine_ruid;
1574 48571958 : 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 219551507 : reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1585 : {
1586 259588924 : rtx x = *xp;
1587 259588924 : enum rtx_code code = x->code;
1588 259588924 : const char *fmt;
1589 259588924 : int i, j;
1590 259588924 : rtx offset = const0_rtx; /* For the REG case below. */
1591 :
1592 259588924 : switch (code)
1593 : {
1594 58509999 : case SET:
1595 58509999 : if (REG_P (SET_DEST (x)))
1596 : {
1597 40037417 : reload_combine_note_use (&SET_SRC (x), insn, ruid, NULL_RTX);
1598 40037417 : return;
1599 : }
1600 : break;
1601 :
1602 648885 : case USE:
1603 : /* If this is the USE of a return value, we can't change it. */
1604 648885 : 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 559876 : rtx reg = XEXP (x, 0);
1608 559876 : unsigned int end_regno = END_REGNO (reg);
1609 1147847 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1610 587971 : reg_state[regno].use_index = -1;
1611 : return;
1612 : }
1613 : break;
1614 :
1615 7520300 : case CLOBBER:
1616 7520300 : if (REG_P (SET_DEST (x)))
1617 : {
1618 : /* No spurious CLOBBERs of pseudo registers may remain. */
1619 7468969 : gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1620 : return;
1621 : }
1622 : break;
1623 :
1624 23587161 : case PLUS:
1625 : /* We are interested in (plus (reg) (const_int)) . */
1626 23587161 : if (!REG_P (XEXP (x, 0))
1627 21143371 : || !CONST_INT_P (XEXP (x, 1)))
1628 : break;
1629 : offset = XEXP (x, 1);
1630 : x = XEXP (x, 0);
1631 : /* Fall through. */
1632 60599012 : case REG:
1633 60599012 : {
1634 60599012 : int regno = REGNO (x);
1635 60599012 : int use_index;
1636 60599012 : int nregs;
1637 :
1638 : /* No spurious USEs of pseudo registers may remain. */
1639 60599012 : gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1640 :
1641 60599012 : nregs = REG_NREGS (x);
1642 :
1643 : /* We can't substitute into multi-hard-reg uses. */
1644 60599012 : if (nregs > 1)
1645 : {
1646 1238100 : while (--nregs >= 0)
1647 825400 : 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 60186312 : 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 60185186 : use_index = --reg_state[regno].use_index;
1661 60185186 : if (use_index < 0)
1662 : return;
1663 :
1664 36342622 : 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 27513716 : reg_state[regno].offset = offset;
1669 27513716 : reg_state[regno].all_offsets_match = true;
1670 27513716 : reg_state[regno].use_ruid = ruid;
1671 : }
1672 : else
1673 : {
1674 8828906 : if (reg_state[regno].use_ruid > ruid)
1675 616 : reg_state[regno].use_ruid = ruid;
1676 :
1677 8828906 : if (! rtx_equal_p (offset, reg_state[regno].offset))
1678 4008733 : reg_state[regno].all_offsets_match = false;
1679 : }
1680 :
1681 36342622 : reg_state[regno].reg_use[use_index].insn = insn;
1682 36342622 : reg_state[regno].reg_use[use_index].ruid = ruid;
1683 36342622 : reg_state[regno].reg_use[use_index].containing_mem = containing_mem;
1684 36342622 : reg_state[regno].reg_use[use_index].usep = xp;
1685 36342622 : return;
1686 : }
1687 :
1688 : case MEM:
1689 150923650 : containing_mem = x;
1690 : break;
1691 :
1692 : default:
1693 : break;
1694 : }
1695 :
1696 : /* Recursively process the components of X. */
1697 150923650 : fmt = GET_RTX_FORMAT (code);
1698 385669078 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1699 : {
1700 234745428 : if (fmt[i] == 'e')
1701 137522654 : reload_combine_note_use (&XEXP (x, i), insn, ruid, containing_mem);
1702 97222774 : else if (fmt[i] == 'E')
1703 : {
1704 30105685 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1705 20265103 : 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 53195678 : move2add_record_mode (rtx reg)
1761 : {
1762 53195678 : int regno, nregs;
1763 53195678 : machine_mode mode = GET_MODE (reg);
1764 :
1765 53195678 : if (GET_CODE (reg) == SUBREG)
1766 : {
1767 3652 : regno = subreg_regno (reg);
1768 3652 : nregs = subreg_nregs (reg);
1769 : }
1770 53192026 : else if (REG_P (reg))
1771 : {
1772 53192026 : regno = REGNO (reg);
1773 53192026 : nregs = REG_NREGS (reg);
1774 : }
1775 : else
1776 0 : gcc_unreachable ();
1777 53855593 : for (int i = nregs - 1; i > 0; i--)
1778 659915 : reg_mode[regno + i] = BLKmode;
1779 53195678 : reg_mode[regno] = mode;
1780 53195678 : }
1781 :
1782 : /* Record that REG is being set to the sum of SYM and OFF. */
1783 :
1784 : static void
1785 2070120 : move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1786 : {
1787 2070120 : int regno = REGNO (reg);
1788 :
1789 2070120 : move2add_record_mode (reg);
1790 2070120 : reg_set_luid[regno] = move2add_luid;
1791 2070120 : reg_base_reg[regno] = -1;
1792 2070120 : reg_symbol_ref[regno] = sym;
1793 2070120 : reg_offset[regno] = INTVAL (off);
1794 2070120 : }
1795 :
1796 : /* Check if REGNO contains a valid value in MODE. */
1797 :
1798 : static bool
1799 208932000 : move2add_valid_value_p (int regno, scalar_int_mode mode)
1800 : {
1801 208932000 : if (reg_set_luid[regno] <= move2add_last_label_luid)
1802 : return false;
1803 :
1804 21170577 : if (mode != reg_mode[regno])
1805 : {
1806 11283133 : scalar_int_mode old_mode;
1807 11283133 : if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1808 7201824 : || !MODES_OK_FOR_MOVE2ADD (mode, old_mode)
1809 519839 : || !REG_CAN_CHANGE_MODE_P (regno, old_mode, mode))
1810 10763294 : 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 519839 : poly_int64 s_off = subreg_lowpart_offset (mode, old_mode);
1816 519839 : s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1817 519839 : 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 10461086 : for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1826 57923 : 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 150345 : move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1840 : rtx_insn *insn)
1841 : {
1842 150345 : rtx set = single_set (insn);
1843 150345 : rtx src = SET_SRC (set);
1844 150345 : int regno = REGNO (reg);
1845 150345 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1846 150345 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1847 150345 : 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 150345 : 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 24702 : if (INTVAL (off) == reg_offset [regno])
1862 23008 : changed = validate_change (insn, &SET_SRC (set), reg, 0);
1863 : }
1864 : else
1865 : {
1866 125643 : struct full_rtx_costs oldcst, newcst;
1867 125643 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1868 :
1869 125643 : get_full_set_rtx_cost (set, &oldcst);
1870 125643 : SET_SRC (set) = tem;
1871 125643 : get_full_set_rtx_cost (set, &newcst);
1872 125643 : SET_SRC (set) = src;
1873 :
1874 125643 : if (costs_lt_p (&newcst, &oldcst, speed)
1875 125643 : && have_add2_insn (reg, new_src))
1876 2913 : changed = validate_change (insn, &SET_SRC (set), tem, 0);
1877 122730 : else if (sym == NULL_RTX && mode != BImode)
1878 : {
1879 121275 : scalar_int_mode narrow_mode;
1880 407525 : FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1881 : {
1882 286250 : if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1883 286250 : && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1884 212778 : == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1885 : {
1886 94095 : rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1887 94095 : rtx narrow_src = gen_int_mode (INTVAL (off),
1888 : narrow_mode);
1889 94095 : rtx new_set
1890 94095 : = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1891 : narrow_reg),
1892 : narrow_src);
1893 94095 : 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 94095 : rtx *setloc = GET_CODE (PATTERN (insn)) == PARALLEL
1899 94095 : ? &XVECEXP (PATTERN (insn), 0, 0) : &PATTERN (insn);
1900 94095 : 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 150345 : move2add_record_sym_value (reg, sym, off);
1911 150345 : 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 1839640 : move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1926 : rtx_insn *insn)
1927 : {
1928 1839640 : rtx set = single_set (insn);
1929 1839640 : rtx src = SET_SRC (set);
1930 1839640 : int regno = REGNO (reg);
1931 1839640 : int min_regno = 0;
1932 1839640 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1933 1839640 : int i;
1934 1839640 : bool changed = false;
1935 1839640 : struct full_rtx_costs oldcst, newcst, mincst;
1936 1839640 : rtx plus_expr;
1937 :
1938 1839640 : init_costs_to_max (&mincst);
1939 1839640 : get_full_set_rtx_cost (set, &oldcst);
1940 :
1941 1839640 : plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1942 1839640 : SET_SRC (set) = plus_expr;
1943 :
1944 171086101 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1945 169246467 : if (move2add_valid_value_p (i, mode)
1946 3615665 : && reg_base_reg[i] < 0
1947 1421151 : && reg_symbol_ref[i] != NULL_RTX
1948 170219771 : && rtx_equal_p (sym, reg_symbol_ref[i]))
1949 : {
1950 36768 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1951 18384 : 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 18384 : 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 18378 : XEXP (plus_expr, 1) = new_src;
1967 18378 : get_full_set_rtx_cost (set, &newcst);
1968 :
1969 18378 : if (costs_lt_p (&newcst, &mincst, speed))
1970 : {
1971 17833 : mincst = newcst;
1972 17833 : min_regno = i;
1973 : }
1974 : }
1975 : }
1976 1839640 : SET_SRC (set) = src;
1977 :
1978 1839640 : 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 1839640 : changed = true;
1991 : }
1992 1839640 : reg_set_luid[regno] = move2add_luid;
1993 1839640 : move2add_record_sym_value (reg, sym, off);
1994 1839640 : return changed;
1995 : }
1996 :
1997 : /* Perform any invalidations necessary for INSN. */
1998 :
1999 : static void
2000 105079088 : reload_cse_move2add_invalidate (rtx_insn *insn)
2001 : {
2002 127722972 : for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
2003 : {
2004 22643884 : 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 105079088 : subrtx_var_iterator::array_type array;
2019 537895148 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
2020 : {
2021 432816060 : rtx mem = *iter;
2022 432816060 : if (mem
2023 432816060 : && MEM_P (mem)
2024 27864739 : && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
2025 : {
2026 1667368 : if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
2027 1667368 : reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
2028 : }
2029 : }
2030 :
2031 105079088 : 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 105079088 : if (any_condjump_p (insn))
2036 : {
2037 4840789 : rtx cnd = fis_get_condition (insn);
2038 :
2039 4840789 : if (cnd != NULL_RTX
2040 4335454 : && GET_CODE (cnd) == NE
2041 1926534 : && REG_P (XEXP (cnd, 0))
2042 1281759 : && !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 1281759 : && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2048 1281758 : && REG_NREGS (XEXP (cnd, 0)) == 1
2049 6122547 : && CONST_INT_P (XEXP (cnd, 1)))
2050 : {
2051 864385 : rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2052 864385 : 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 105079088 : if (CALL_P (insn))
2059 : {
2060 4624609 : function_abi callee_abi = insn_callee_abi (insn);
2061 430088637 : for (int i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2062 425464028 : if (reg_mode[i] != VOIDmode
2063 21417295 : && reg_mode[i] != BLKmode
2064 446323832 : && callee_abi.clobbers_reg_p (reg_mode[i], i))
2065 : /* Reset the information about this register. */
2066 7944800 : reg_mode[i] = VOIDmode;
2067 : }
2068 105079088 : }
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 1043685 : reload_cse_move2add (rtx_insn *first)
2074 : {
2075 1043685 : int i;
2076 1043685 : rtx_insn *insn;
2077 1043685 : bool changed = false;
2078 :
2079 97062705 : for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2080 : {
2081 96019020 : reg_set_luid[i] = 0;
2082 96019020 : reg_offset[i] = 0;
2083 96019020 : reg_base_reg[i] = 0;
2084 96019020 : reg_symbol_ref[i] = NULL_RTX;
2085 96019020 : reg_mode[i] = VOIDmode;
2086 : }
2087 :
2088 1043685 : move2add_last_label_luid = 0;
2089 1043685 : move2add_luid = 2;
2090 136129717 : for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
2091 : {
2092 135086032 : rtx set;
2093 :
2094 135086032 : if (LABEL_P (insn))
2095 : {
2096 5150000 : 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 5150000 : move2add_luid++;
2101 140236032 : continue;
2102 : }
2103 129936032 : if (! INSN_P (insn))
2104 22866959 : continue;
2105 107069073 : set = single_set (insn);
2106 : /* For simplicity, we only perform this optimization on
2107 : single-sets. */
2108 107069073 : scalar_int_mode mode;
2109 107069073 : if (set
2110 54235116 : && REG_P (SET_DEST (set))
2111 144002834 : && is_a <scalar_int_mode> (GET_MODE (SET_DEST (set)), &mode))
2112 : {
2113 27341700 : rtx reg = SET_DEST (set);
2114 27341700 : int regno = REGNO (reg);
2115 27341700 : 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 27341700 : if (move2add_valid_value_p (regno, mode)
2120 27341700 : && 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 3835169 : if (CONST_INT_P (src)
2136 325516 : && reg_base_reg[regno] < 0
2137 151083 : && reg_symbol_ref[regno] == NULL_RTX)
2138 : {
2139 148578 : changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
2140 : src, insn);
2141 148578 : 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 3686591 : else if (REG_P (src)
2155 464092 : && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
2156 117925 : && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
2157 3804516 : && move2add_valid_value_p (REGNO (src), mode))
2158 : {
2159 92095 : rtx_insn *next = next_nonnote_nondebug_insn (insn);
2160 92095 : rtx set = NULL_RTX;
2161 92095 : if (next)
2162 92084 : set = single_set (next);
2163 92084 : if (set
2164 71702 : && SET_DEST (set) == reg
2165 6941 : && GET_CODE (SET_SRC (set)) == PLUS
2166 777 : && XEXP (SET_SRC (set), 0) == reg
2167 772 : && CONST_INT_P (XEXP (SET_SRC (set), 1)))
2168 : {
2169 534 : rtx src3 = XEXP (SET_SRC (set), 1);
2170 534 : unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
2171 534 : HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
2172 534 : HOST_WIDE_INT regno_offset = reg_offset[regno];
2173 534 : rtx new_src =
2174 1068 : gen_int_mode (added_offset
2175 534 : + base_offset
2176 534 : - regno_offset,
2177 : mode);
2178 534 : bool success = false;
2179 534 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
2180 :
2181 534 : 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 497 : rtx old_src = SET_SRC (set);
2188 497 : struct full_rtx_costs oldcst, newcst;
2189 497 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
2190 :
2191 497 : get_full_set_rtx_cost (set, &oldcst);
2192 497 : SET_SRC (set) = tem;
2193 497 : get_full_set_src_cost (tem, mode, &newcst);
2194 497 : SET_SRC (set) = old_src;
2195 497 : costs_add_n_insns (&oldcst, 1);
2196 :
2197 497 : rtx *setloc = GET_CODE (PATTERN (next)) == PARALLEL
2198 497 : ? &XVECEXP (PATTERN (next), 0, 0) : &PATTERN (next);
2199 497 : if (*setloc == set
2200 497 : && costs_lt_p (&newcst, &oldcst, speed)
2201 994 : && have_add2_insn (reg, new_src))
2202 : {
2203 497 : rtx newpat = gen_rtx_SET (reg, tem);
2204 497 : success
2205 497 : = validate_change (next, setloc, newpat, 0);
2206 : }
2207 : }
2208 534 : if (success)
2209 534 : delete_insn (insn);
2210 534 : changed |= success;
2211 534 : 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 534 : reload_cse_move2add_invalidate (insn);
2218 534 : move2add_record_mode (reg);
2219 534 : reg_offset[regno]
2220 534 : = trunc_int_for_mode (added_offset + base_offset,
2221 : mode);
2222 534 : continue;
2223 534 : }
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 27192588 : if ((GET_CODE (src) == SYMBOL_REF
2236 25411630 : || (GET_CODE (src) == CONST
2237 60677 : && GET_CODE (XEXP (src, 0)) == PLUS
2238 60469 : && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF
2239 60449 : && CONST_INT_P (XEXP (XEXP (src, 0), 1))))
2240 27253037 : && dbg_cnt (cse2_move2add))
2241 : {
2242 1841407 : rtx sym, off;
2243 :
2244 1841407 : if (GET_CODE (src) == SYMBOL_REF)
2245 : {
2246 1780958 : sym = src;
2247 1780958 : off = const0_rtx;
2248 : }
2249 : else
2250 : {
2251 60449 : sym = XEXP (XEXP (src, 0), 0);
2252 60449 : 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 1841407 : if (move2add_valid_value_p (regno, mode)
2258 191551 : && reg_base_reg[regno] < 0
2259 125800 : && reg_symbol_ref[regno] != NULL_RTX
2260 1892934 : && rtx_equal_p (sym, reg_symbol_ref[regno]))
2261 1767 : 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 1839640 : changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2267 :
2268 1841407 : continue;
2269 1841407 : }
2270 : }
2271 105078554 : reload_cse_move2add_invalidate (insn);
2272 : }
2273 1043685 : 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 61541706 : move2add_note_store (rtx dst, const_rtx set, void *data)
2283 : {
2284 61541706 : rtx_insn *insn = (rtx_insn *) data;
2285 61541706 : unsigned int regno = 0;
2286 61541706 : scalar_int_mode mode;
2287 :
2288 61541706 : if (GET_CODE (dst) == SUBREG)
2289 3652 : regno = subreg_regno (dst);
2290 61538054 : else if (REG_P (dst))
2291 44138273 : regno = REGNO (dst);
2292 : else
2293 61541706 : return;
2294 :
2295 44141925 : if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2296 16795230 : goto invalidate;
2297 :
2298 27346695 : if (GET_CODE (set) == SET)
2299 : {
2300 26794873 : rtx note, sym = NULL_RTX;
2301 26794873 : rtx off;
2302 :
2303 26794873 : note = find_reg_equal_equiv_note (insn);
2304 26794873 : if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2305 : {
2306 70000 : sym = XEXP (note, 0);
2307 70000 : off = const0_rtx;
2308 : }
2309 4194458 : else if (note && GET_CODE (XEXP (note, 0)) == CONST
2310 10347 : && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2311 10155 : && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2312 10135 : && 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 80135 : if (sym != NULL_RTX)
2319 : {
2320 80135 : move2add_record_sym_value (dst, sym, off);
2321 80135 : return;
2322 : }
2323 : }
2324 :
2325 27266560 : if (GET_CODE (set) == SET
2326 26714738 : && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2327 26713704 : && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2328 : {
2329 26710626 : rtx src = SET_SRC (set);
2330 26710626 : rtx base_reg;
2331 26710626 : unsigned HOST_WIDE_INT offset;
2332 26710626 : int base_regno;
2333 :
2334 26710626 : switch (GET_CODE (src))
2335 : {
2336 6007312 : case PLUS:
2337 6007312 : if (REG_P (XEXP (src, 0)))
2338 : {
2339 5707654 : base_reg = XEXP (src, 0);
2340 :
2341 5707654 : if (CONST_INT_P (XEXP (src, 1)))
2342 4921645 : offset = UINTVAL (XEXP (src, 1));
2343 786009 : else if (REG_P (XEXP (src, 1))
2344 786009 : && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2345 : {
2346 84744 : if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2347 84744 : && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2348 7039 : offset = reg_offset[REGNO (XEXP (src, 1))];
2349 : /* Maybe the first register is known to be a
2350 : constant. */
2351 77705 : else if (move2add_valid_value_p (REGNO (base_reg), mode)
2352 20512 : && reg_base_reg[REGNO (base_reg)] < 0
2353 78598 : && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2354 : {
2355 781 : offset = reg_offset[REGNO (base_reg)];
2356 781 : base_reg = XEXP (src, 1);
2357 : }
2358 : else
2359 76924 : goto invalidate;
2360 : }
2361 : else
2362 701265 : goto invalidate;
2363 :
2364 : break;
2365 : }
2366 :
2367 299658 : goto invalidate;
2368 :
2369 : case REG:
2370 : base_reg = src;
2371 : offset = 0;
2372 : break;
2373 :
2374 4333648 : case CONST_INT:
2375 : /* Start tracking the register as a constant. */
2376 4333648 : reg_base_reg[regno] = -1;
2377 4333648 : reg_symbol_ref[regno] = NULL_RTX;
2378 4333648 : reg_offset[regno] = INTVAL (SET_SRC (set));
2379 : /* We assign the same luid to all registers set to constants. */
2380 4333648 : reg_set_luid[regno] = move2add_last_label_luid + 1;
2381 4333648 : move2add_record_mode (dst);
2382 4333648 : return;
2383 :
2384 11672470 : default:
2385 11672470 : goto invalidate;
2386 : }
2387 :
2388 9626661 : 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 9626661 : if (!move2add_valid_value_p (base_regno, mode))
2393 : {
2394 7063234 : reg_base_reg[base_regno] = base_regno;
2395 7063234 : reg_symbol_ref[base_regno] = NULL_RTX;
2396 7063234 : reg_offset[base_regno] = 0;
2397 7063234 : reg_set_luid[base_regno] = move2add_luid;
2398 7063234 : gcc_assert (GET_MODE (base_reg) == mode);
2399 7063234 : move2add_record_mode (base_reg);
2400 : }
2401 :
2402 : /* Copy base information from our base register. */
2403 9626661 : reg_set_luid[regno] = reg_set_luid[base_regno];
2404 9626661 : reg_base_reg[regno] = reg_base_reg[base_regno];
2405 9626661 : reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2406 :
2407 : /* Compute the sum of the offsets or constants. */
2408 9626661 : reg_offset[regno]
2409 9626661 : = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2410 :
2411 9626661 : move2add_record_mode (dst);
2412 9626661 : }
2413 : else
2414 : {
2415 555934 : invalidate:
2416 : /* Invalidate the contents of the register. */
2417 30101481 : move2add_record_mode (dst);
2418 30101481 : 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 285722 : pass_postreload_cse (gcc::context *ctxt)
2441 571444 : : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2442 : {}
2443 :
2444 : /* opt_pass methods: */
2445 1471370 : bool gate (function *) final override
2446 : {
2447 1471370 : 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 1043685 : pass_postreload_cse::execute (function *fun)
2456 : {
2457 1043685 : if (!dbg_cnt (postreload_cse))
2458 : return 0;
2459 :
2460 : /* Do a very simple CSE pass over just the hard registers. */
2461 1043685 : reload_cse_regs (get_insns ());
2462 : /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2463 : Remove any EH edges associated with them. */
2464 1043685 : if (fun->can_throw_non_call_exceptions
2465 1043685 : && purge_all_dead_edges ())
2466 119 : cleanup_cfg (0);
2467 :
2468 : return 0;
2469 : }
2470 :
2471 : } // anon namespace
2472 :
2473 : rtl_opt_pass *
2474 285722 : make_pass_postreload_cse (gcc::context *ctxt)
2475 : {
2476 285722 : return new pass_postreload_cse (ctxt);
2477 : }
|