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 1070192 : reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
64 : {
65 1070192 : bool moves_converted;
66 1070192 : reload_cse_regs_1 ();
67 1070192 : reload_combine ();
68 1070192 : moves_converted = reload_cse_move2add (first);
69 1070192 : if (flag_expensive_optimizations)
70 : {
71 988491 : if (moves_converted)
72 6258 : reload_combine ();
73 988491 : reload_cse_regs_1 ();
74 : }
75 1070192 : }
76 :
77 : /* Try to simplify INSN. Return true if the CFG may have changed. */
78 : static bool
79 225970634 : reload_cse_simplify (rtx_insn *insn, rtx testreg)
80 : {
81 225970634 : rtx body = PATTERN (insn);
82 225970634 : basic_block insn_bb = BLOCK_FOR_INSN (insn);
83 225970634 : 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 225970634 : if (NO_FUNCTION_CSE && CALL_P (insn))
88 : return false;
89 :
90 : /* Remember if this insn has been sp += const_int. */
91 216543885 : rtx sp_set = set_for_reg_notes (insn);
92 216543885 : rtx sp_addend = NULL_RTX;
93 216543885 : if (sp_set
94 70476263 : && SET_DEST (sp_set) == stack_pointer_rtx
95 3337663 : && GET_CODE (SET_SRC (sp_set)) == PLUS
96 3307197 : && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
97 3307094 : && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
98 216543885 : sp_addend = XEXP (SET_SRC (sp_set), 1);
99 :
100 216543885 : if (GET_CODE (body) == SET)
101 : {
102 91016313 : 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 91016313 : count += reload_cse_simplify_set (body, insn);
110 :
111 91016313 : if (!count && cselib_redundant_set_p (body))
112 : {
113 242332 : if (check_for_inc_dec (insn))
114 242332 : delete_insn_and_edges (insn);
115 : /* We're done with this insn. */
116 242332 : goto done;
117 : }
118 :
119 90773981 : if (count > 0)
120 151392 : apply_change_group ();
121 : else
122 90622589 : reload_cse_simplify_operands (insn, testreg);
123 : }
124 125527572 : else if (GET_CODE (body) == PARALLEL)
125 : {
126 14445730 : int i;
127 14445730 : int count = 0;
128 14445730 : 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 14445730 : if (asm_noperands (body) >= 0)
134 : {
135 583079 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
136 : {
137 449520 : rtx part = XVECEXP (body, 0, i);
138 449520 : if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
139 188390 : 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 28889392 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
146 : {
147 28885505 : rtx part = XVECEXP (body, 0, i);
148 28885505 : if (GET_CODE (part) == SET)
149 : {
150 14354813 : if (! cselib_redundant_set_p (part))
151 : break;
152 3952 : if (REG_P (SET_DEST (part))
153 3952 : && REG_FUNCTION_VALUE_P (SET_DEST (part)))
154 : {
155 0 : if (value)
156 : break;
157 : value = SET_DEST (part);
158 : }
159 : }
160 14530692 : else if (GET_CODE (part) != CLOBBER && GET_CODE (part) != USE)
161 : break;
162 : }
163 :
164 14445730 : if (i < 0)
165 : {
166 3887 : if (check_for_inc_dec (insn))
167 3887 : delete_insn_and_edges (insn);
168 : /* We're done with this insn. */
169 3887 : goto done;
170 : }
171 :
172 : /* It's not a no-op, but we can try to simplify it. */
173 44121350 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
174 29679507 : if (GET_CODE (XVECEXP (body, 0, i)) == SET)
175 15152666 : count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
176 :
177 14441843 : if (count > 0)
178 5654 : apply_change_group ();
179 : else
180 14436189 : 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 216297666 : if (sp_addend
186 3307094 : && SET_DEST (sp_set) == stack_pointer_rtx
187 3307094 : && REG_P (SET_SRC (sp_set)))
188 3055 : set_dst_reg_note (insn, REG_EQUAL,
189 3055 : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
190 : sp_addend), stack_pointer_rtx);
191 :
192 216294611 : done:
193 433084283 : 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 2058683 : reload_cse_regs_1 (void)
215 : {
216 2058683 : bool cfg_changed = false;
217 2058683 : basic_block bb;
218 2058683 : rtx_insn *insn;
219 2058683 : rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
220 :
221 2058683 : cselib_init (CSELIB_RECORD_MEMORY);
222 2058683 : init_alias_analysis ();
223 :
224 24063795 : 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 22005112 : rtx_insn *implicit_set;
230 :
231 22005112 : implicit_set = NULL;
232 22005112 : if (EDGE_COUNT (bb->preds) <= 3)
233 : {
234 21442610 : edge e;
235 21442610 : edge_iterator ei;
236 21442610 : rtx src = NULL_RTX;
237 21442610 : rtx dest = NULL_RTX;
238 :
239 : /* Iterate over each incoming edge and see if they
240 : all have the same implicit set. */
241 25109061 : FOR_EACH_EDGE (e, ei, bb->preds)
242 : {
243 : /* Skip the entry/exit block. */
244 22196569 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
245 : break;
246 :
247 : /* Verify this block ends with a suitable condjump */
248 20137942 : rtx_insn *condjump = BB_END (e->src);
249 20137942 : if (!condjump || ! any_condjump_p (condjump))
250 : break;
251 :
252 : /* get_condition reverses the condition only when the else arm
253 : is a LABEL_REF, so a jump that returns in one arm would give
254 : the condition of the other edge. */
255 15293319 : if (!JUMP_LABEL (condjump) || !LABEL_P (JUMP_LABEL (condjump)))
256 : break;
257 :
258 : /* This predecessor ends with a possible equivalence
259 : producing conditional branch. Extract the condition
260 : and try to use it to create an equivalence. */
261 15293319 : rtx cond = get_condition (condjump, NULL, false, true);
262 15293319 : if (!cond)
263 : break;
264 :
265 14040458 : if ((e->flags & EDGE_FALLTHRU) != 0
266 14040458 : ? GET_CODE (cond) == NE
267 5699841 : : GET_CODE (cond) == EQ)
268 : {
269 : /* If this is the first time through record
270 : the source and destination. */
271 5729041 : if (!dest)
272 : {
273 5557629 : dest = XEXP (cond, 0);
274 5557629 : src = XEXP (cond, 1);
275 : }
276 : /* If this is not the first time through, then
277 : verify the source and destination match. */
278 171412 : else if (rtx_equal_p (dest, XEXP (cond, 0))
279 171412 : && rtx_equal_p (src, XEXP (cond, 1)))
280 : ;
281 : else
282 : break;
283 :
284 : /* A few more checks. First make sure we're dealing with
285 : integer modes, second make sure the values aren't clobbered
286 : by the conditional branch itself. Do this for every
287 : conditional jump participating in creation of the
288 : equivalence. */
289 5627978 : if (!REG_P (dest)
290 3921040 : || !(REG_P (src) || CONST_INT_P (src))
291 3666455 : || GET_MODE_CLASS (GET_MODE (dest)) != MODE_INT
292 3666451 : || reg_set_p (dest, condjump)
293 9294429 : || reg_set_p (src, condjump))
294 : break;
295 :
296 : }
297 : else
298 : break;
299 : }
300 :
301 : /* If all the incoming edges had the same implicit
302 : set, then create a dummy insn for that set.
303 :
304 : It will be entered into the cselib tables before
305 : we process the first real insn in this block. */
306 21442610 : if (dest && ei_end_p (ei))
307 : {
308 2912492 : rtx_insn *i;
309 2912492 : bool useful = false;
310 22340270 : FOR_BB_INSNS (bb, i)
311 : {
312 20623996 : if (!NONDEBUG_INSN_P (i))
313 12565287 : continue;
314 8058709 : rtx s = single_set (i);
315 8058709 : if (s
316 7644998 : && rtx_equal_p (SET_DEST (s), dest)
317 8575717 : && rtx_equal_p (SET_SRC (s), src))
318 : {
319 : useful = true;
320 : break;
321 : }
322 8035720 : if (reg_set_p (dest, i))
323 : break;
324 : }
325 2912492 : if (useful)
326 22989 : implicit_set = make_insn_raw (gen_rtx_SET (dest, src));
327 : }
328 : }
329 :
330 293773145 : FOR_BB_INSNS (bb, insn)
331 : {
332 271768033 : if (INSN_P (insn))
333 : {
334 : /* If we recorded an implicit set, enter it
335 : into the tables before the first real insn.
336 :
337 : We have to do it this way because a CODE_LABEL
338 : will flush the cselib tables. */
339 225970634 : if (implicit_set)
340 : {
341 22989 : cselib_process_insn (implicit_set);
342 22989 : implicit_set = NULL;
343 : }
344 225970634 : cfg_changed |= reload_cse_simplify (insn, testreg);
345 : }
346 :
347 271768033 : cselib_process_insn (insn);
348 : }
349 : }
350 :
351 : /* Clean up. */
352 2058683 : end_alias_analysis ();
353 2058683 : cselib_finish ();
354 2058683 : if (cfg_changed)
355 85 : cleanup_cfg (0);
356 2058683 : }
357 :
358 : /* Try to simplify a single SET instruction. SET is the set pattern.
359 : INSN is the instruction it came from.
360 : This function only handles one case: if we set a register to a value
361 : which is not a register, we try to find that value in some other register
362 : and change the set into a register copy. */
363 :
364 : static int
365 106168979 : reload_cse_simplify_set (rtx set, rtx_insn *insn)
366 : {
367 106168979 : int did_change = 0;
368 106168979 : int dreg;
369 106168979 : rtx src;
370 106168979 : reg_class_t dclass;
371 106168979 : int old_cost;
372 106168979 : cselib_val *val;
373 106168979 : struct elt_loc_list *l;
374 106168979 : enum rtx_code extend_op = UNKNOWN;
375 106168979 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
376 :
377 106168979 : dreg = true_regnum (SET_DEST (set));
378 106168979 : if (dreg < 0)
379 : return 0;
380 :
381 71763235 : src = SET_SRC (set);
382 71763235 : if (side_effects_p (src) || true_regnum (src) >= 0)
383 : return 0;
384 :
385 60352675 : dclass = REGNO_REG_CLASS (dreg);
386 :
387 : /* When replacing a memory with a register, we need to honor assumptions
388 : that combine made wrt the contents of sign bits. We'll do this by
389 : generating an extend instruction instead of a reg->reg copy. Thus
390 : the destination must be a register that we can widen. */
391 60352675 : if (MEM_P (src)
392 : && (extend_op = load_extend_op (GET_MODE (src))) != UNKNOWN
393 : && !REG_P (SET_DEST (set)))
394 : return 0;
395 :
396 60352675 : val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
397 60352675 : if (! val)
398 : return 0;
399 :
400 : /* If memory loads are cheaper than register copies, don't change them. */
401 5770900 : if (MEM_P (src))
402 641217 : old_cost = memory_move_cost (GET_MODE (src), dclass, true);
403 5129683 : else if (REG_P (src))
404 0 : old_cost = register_move_cost (GET_MODE (src),
405 0 : REGNO_REG_CLASS (REGNO (src)), dclass);
406 : else
407 5129683 : old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
408 :
409 11523175 : for (l = val->locs; l; l = l->next)
410 : {
411 5752275 : rtx this_rtx = l->loc;
412 5752275 : int this_cost;
413 :
414 5752275 : if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx))
415 : {
416 1983055 : if (extend_op != UNKNOWN)
417 : {
418 : wide_int result;
419 :
420 : if (!CONST_SCALAR_INT_P (this_rtx))
421 : continue;
422 :
423 : switch (extend_op)
424 : {
425 : case ZERO_EXTEND:
426 : result = wide_int::from (rtx_mode_t (this_rtx,
427 : GET_MODE (src)),
428 : BITS_PER_WORD, UNSIGNED);
429 : break;
430 : case SIGN_EXTEND:
431 : result = wide_int::from (rtx_mode_t (this_rtx,
432 : GET_MODE (src)),
433 : BITS_PER_WORD, SIGNED);
434 : break;
435 : default:
436 : gcc_unreachable ();
437 : }
438 : this_rtx = immed_wide_int_const (result, word_mode);
439 : }
440 :
441 1983055 : this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
442 : }
443 3769220 : else if (REG_P (this_rtx))
444 : {
445 826185 : if (extend_op != UNKNOWN)
446 : {
447 : this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
448 : this_cost = set_src_cost (this_rtx, word_mode, speed);
449 : }
450 : else
451 826185 : this_cost = register_move_cost (GET_MODE (this_rtx),
452 826185 : REGNO_REG_CLASS (REGNO (this_rtx)),
453 : dclass);
454 : }
455 : else
456 2943035 : continue;
457 :
458 : /* If equal costs, prefer registers over anything else. That
459 : tends to lead to smaller instructions on some machines. */
460 2809240 : if (this_cost < old_cost
461 2652684 : || (this_cost == old_cost
462 1988296 : && REG_P (this_rtx)
463 13336 : && !REG_P (SET_SRC (set))))
464 : {
465 157381 : if (extend_op != UNKNOWN
466 : && REG_CAN_CHANGE_MODE_P (REGNO (SET_DEST (set)),
467 : GET_MODE (SET_DEST (set)), word_mode))
468 : {
469 : rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
470 : ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
471 : validate_change (insn, &SET_DEST (set), wide_dest, 1);
472 : }
473 :
474 157381 : validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
475 157381 : old_cost = this_cost, did_change = 1;
476 : }
477 : }
478 :
479 : return did_change;
480 : }
481 :
482 : /* Try to replace operands in INSN with equivalent values that are already
483 : in registers. This can be viewed as optional reloading.
484 :
485 : For each non-register operand in the insn, see if any hard regs are
486 : known to be equivalent to that operand. Record the alternatives which
487 : can accept these hard registers. Among all alternatives, select the
488 : ones which are better or equal to the one currently matching, where
489 : "better" is in terms of '?' and '!' constraints. Among the remaining
490 : alternatives, select the one which replaces most operands with
491 : hard registers. */
492 :
493 : static int
494 105058778 : reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
495 : {
496 105058778 : int i, j;
497 :
498 : /* For each operand, all registers that are equivalent to it. */
499 105058778 : HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
500 :
501 105058778 : const char *constraints[MAX_RECOG_OPERANDS];
502 :
503 : /* Vector recording how bad an alternative is. */
504 105058778 : int *alternative_reject;
505 : /* Vector recording how many registers can be introduced by choosing
506 : this alternative. */
507 105058778 : int *alternative_nregs;
508 : /* Array of vectors recording, for each operand and each alternative,
509 : which hard register to substitute, or -1 if the operand should be
510 : left as it is. */
511 105058778 : int *op_alt_regno[MAX_RECOG_OPERANDS];
512 : /* Array of alternatives, sorted in order of decreasing desirability. */
513 105058778 : int *alternative_order;
514 :
515 105058778 : extract_constrain_insn (insn);
516 :
517 105058778 : if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
518 : return 0;
519 :
520 90774663 : alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
521 90774663 : alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
522 90774663 : alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
523 90774663 : memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
524 90774663 : memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
525 :
526 : /* For each operand, find out which regs are equivalent. */
527 293511539 : for (i = 0; i < recog_data.n_operands; i++)
528 : {
529 : cselib_val *v;
530 : struct elt_loc_list *l;
531 : rtx op;
532 :
533 202736876 : CLEAR_HARD_REG_SET (equiv_regs[i]);
534 :
535 : /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem
536 : right, so avoid the problem here. Similarly NOTE_INSN_DELETED_LABEL.
537 : Likewise if we have a constant and the insn pattern doesn't tell us
538 : the mode we need. */
539 202736876 : if (LABEL_P (recog_data.operand[i])
540 202722102 : || (NOTE_P (recog_data.operand[i])
541 116 : && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
542 202721986 : || (CONSTANT_P (recog_data.operand[i])
543 34617855 : && recog_data.operand_mode[i] == VOIDmode))
544 644652 : continue;
545 :
546 202092224 : op = recog_data.operand[i];
547 202092224 : if (MEM_P (op) && load_extend_op (GET_MODE (op)) != UNKNOWN)
548 : {
549 : rtx set = single_set (insn);
550 :
551 : /* We might have multiple sets, some of which do implicit
552 : extension. Punt on this for now. */
553 : if (! set)
554 : continue;
555 : /* If the destination is also a MEM or a STRICT_LOW_PART, no
556 : extension applies.
557 : Also, if there is an explicit extension, we don't have to
558 : worry about an implicit one. */
559 : else if (MEM_P (SET_DEST (set))
560 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART
561 : || GET_CODE (SET_SRC (set)) == ZERO_EXTEND
562 : || GET_CODE (SET_SRC (set)) == SIGN_EXTEND)
563 : ; /* Continue ordinary processing. */
564 : /* If the register cannot change mode to word_mode, it follows that
565 : it cannot have been used in word_mode. */
566 : else if (REG_P (SET_DEST (set))
567 : && !REG_CAN_CHANGE_MODE_P (REGNO (SET_DEST (set)),
568 : GET_MODE (SET_DEST (set)),
569 : word_mode))
570 : ; /* Continue ordinary processing. */
571 : /* If this is a straight load, make the extension explicit. */
572 : else if (REG_P (SET_DEST (set))
573 : && recog_data.n_operands == 2
574 : && SET_SRC (set) == op
575 : && SET_DEST (set) == recog_data.operand[1-i])
576 : {
577 : validate_change (insn, recog_data.operand_loc[i],
578 : gen_rtx_fmt_e (load_extend_op (GET_MODE (op)),
579 : word_mode, op),
580 : 1);
581 : validate_change (insn, recog_data.operand_loc[1-i],
582 : gen_rtx_REG (word_mode, REGNO (SET_DEST (set))),
583 : 1);
584 : if (! apply_change_group ())
585 : return 0;
586 : return reload_cse_simplify_operands (insn, testreg);
587 : }
588 : else
589 : /* ??? There might be arithmetic operations with memory that are
590 : safe to optimize, but is it worth the trouble? */
591 : continue;
592 : }
593 :
594 202092224 : if (side_effects_p (op))
595 4561917 : continue;
596 197530307 : v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
597 197530307 : if (! v)
598 131024881 : continue;
599 :
600 196194698 : for (l = v->locs; l; l = l->next)
601 129689272 : if (REG_P (l->loc))
602 69127146 : SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
603 : }
604 :
605 90774663 : alternative_mask preferred = get_preferred_alternatives (insn);
606 384286202 : for (i = 0; i < recog_data.n_operands; i++)
607 : {
608 202736876 : machine_mode mode;
609 202736876 : int regno;
610 202736876 : const char *p;
611 :
612 202736876 : op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
613 3030562146 : for (j = 0; j < recog_data.n_alternatives; j++)
614 2827825270 : op_alt_regno[i][j] = -1;
615 :
616 202736876 : p = constraints[i] = recog_data.constraints[i];
617 202736876 : mode = recog_data.operand_mode[i];
618 :
619 : /* Add the reject values for each alternative given by the constraints
620 : for this operand. */
621 202736876 : j = 0;
622 8151781539 : while (*p != '\0')
623 : {
624 7949044663 : char c = *p++;
625 7949044663 : if (c == ',')
626 2615180037 : j++;
627 5333864626 : else if (c == '?')
628 640920471 : alternative_reject[j] += 3;
629 4692944155 : else if (c == '!')
630 18257555 : alternative_reject[j] += 300;
631 : }
632 :
633 : /* We won't change operands which are already registers. We
634 : also don't want to modify output operands. */
635 202736876 : regno = true_regnum (recog_data.operand[i]);
636 202736876 : if (regno >= 0
637 80839588 : || constraints[i][0] == '='
638 60870020 : || constraints[i][0] == '+')
639 141982010 : continue;
640 :
641 5771712270 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
642 : {
643 5710957404 : enum reg_class rclass = NO_REGS;
644 :
645 5710957404 : if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
646 5710196825 : continue;
647 :
648 760579 : set_mode_and_regno (testreg, mode, regno);
649 :
650 : /* We found a register equal to this operand. Now look for all
651 : alternatives that can accept this register and have not been
652 : assigned a register they can use yet. */
653 760579 : j = 0;
654 760579 : p = constraints[i];
655 41933405 : for (;;)
656 : {
657 41933405 : char c = *p;
658 :
659 41933405 : switch (c)
660 : {
661 190451 : case 'g':
662 190451 : rclass = reg_class_subunion[rclass][GENERAL_REGS];
663 190451 : break;
664 :
665 26558924 : default:
666 26558924 : rclass
667 26558924 : = (reg_class_subunion
668 26558924 : [rclass]
669 26558924 : [reg_class_for_constraint (lookup_constraint (p))]);
670 26558924 : break;
671 :
672 15184030 : case ',': case '\0':
673 : /* See if REGNO fits this alternative, and set it up as the
674 : replacement register if we don't have one for this
675 : alternative yet and the operand being replaced is not
676 : a cheap CONST_INT. */
677 15184030 : if (op_alt_regno[i][j] == -1
678 15116603 : && TEST_BIT (preferred, j)
679 10281521 : && reg_fits_class_p (testreg, rclass, 0, mode)
680 17687723 : && (!CONST_INT_P (recog_data.operand[i])
681 2377575 : || (set_src_cost (recog_data.operand[i], mode,
682 : optimize_bb_for_speed_p
683 2377575 : (BLOCK_FOR_INSN (insn)))
684 2377575 : > set_src_cost (testreg, mode,
685 : optimize_bb_for_speed_p
686 2377575 : (BLOCK_FOR_INSN (insn))))))
687 : {
688 126806 : alternative_nregs[j]++;
689 126806 : op_alt_regno[i][j] = regno;
690 : }
691 15184030 : j++;
692 15184030 : rclass = NO_REGS;
693 15184030 : break;
694 : }
695 41933405 : p += CONSTRAINT_LEN (c, p);
696 :
697 41933405 : if (c == '\0')
698 : break;
699 : }
700 : }
701 : }
702 :
703 : /* The loop below sets alternative_order[0] but -Wmaybe-uninitialized
704 : can't know that. Clear it here to avoid the warning. */
705 90774663 : alternative_order[0] = 0;
706 90774663 : gcc_assert (!recog_data.n_alternatives
707 : || (which_alternative >= 0
708 : && which_alternative < recog_data.n_alternatives));
709 :
710 : /* Record all alternatives which are better or equal to the currently
711 : matching one in the alternative_order array. */
712 1437168176 : for (i = j = 0; i < recog_data.n_alternatives; i++)
713 1346393513 : if (alternative_reject[i] <= alternative_reject[which_alternative])
714 783277185 : alternative_order[j++] = i;
715 90774663 : recog_data.n_alternatives = j;
716 :
717 : /* Sort it. Given a small number of alternatives, a dumb algorithm
718 : won't hurt too much. */
719 783277185 : for (i = 0; i < recog_data.n_alternatives - 1; i++)
720 : {
721 692502522 : int best = i;
722 692502522 : int best_reject = alternative_reject[alternative_order[i]];
723 692502522 : int best_nregs = alternative_nregs[alternative_order[i]];
724 :
725 4822629770 : for (j = i + 1; j < recog_data.n_alternatives; j++)
726 : {
727 4130127248 : int this_reject = alternative_reject[alternative_order[j]];
728 4130127248 : int this_nregs = alternative_nregs[alternative_order[j]];
729 :
730 4130127248 : if (this_reject < best_reject
731 4123774418 : || (this_reject == best_reject && this_nregs > best_nregs))
732 : {
733 6426420 : best = j;
734 6426420 : best_reject = this_reject;
735 6426420 : best_nregs = this_nregs;
736 : }
737 : }
738 :
739 692502522 : std::swap (alternative_order[best], alternative_order[i]);
740 : }
741 :
742 : /* Substitute the operands as determined by op_alt_regno for the best
743 : alternative. */
744 90774663 : j = alternative_order[0];
745 :
746 293511539 : for (i = 0; i < recog_data.n_operands; i++)
747 : {
748 202736876 : machine_mode mode = recog_data.operand_mode[i];
749 202736876 : if (op_alt_regno[i][j] == -1)
750 202688261 : continue;
751 :
752 48615 : validate_change (insn, recog_data.operand_loc[i],
753 : gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
754 : }
755 :
756 92154186 : for (i = recog_data.n_dups - 1; i >= 0; i--)
757 : {
758 1379523 : int op = recog_data.dup_num[i];
759 1379523 : machine_mode mode = recog_data.operand_mode[op];
760 :
761 1379523 : if (op_alt_regno[op][j] == -1)
762 1379187 : continue;
763 :
764 336 : validate_change (insn, recog_data.dup_loc[i],
765 : gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
766 : }
767 :
768 90774663 : return apply_change_group ();
769 : }
770 :
771 : /* If reload couldn't use reg+reg+offset addressing, try to use reg+reg
772 : addressing now.
773 : This code might also be useful when reload gave up on reg+reg addressing
774 : because of clashes between the return register and INDEX_REG_CLASS. */
775 :
776 : /* The maximum number of uses of a register we can keep track of to
777 : replace them with reg+reg addressing. */
778 : #define RELOAD_COMBINE_MAX_USES 16
779 :
780 : /* Describes a recorded use of a register. */
781 : struct reg_use
782 : {
783 : /* The insn where a register has been used. */
784 : rtx_insn *insn;
785 : /* Points to the memory reference enclosing the use, if any, NULL_RTX
786 : otherwise. */
787 : rtx containing_mem;
788 : /* Location of the register within INSN. */
789 : rtx *usep;
790 : /* The reverse uid of the insn. */
791 : int ruid;
792 : };
793 :
794 : /* If the register is used in some unknown fashion, USE_INDEX is negative.
795 : If it is dead, USE_INDEX is RELOAD_COMBINE_MAX_USES, and STORE_RUID
796 : indicates where it is first set or clobbered.
797 : Otherwise, USE_INDEX is the index of the last encountered use of the
798 : register (which is first among these we have seen since we scan backwards).
799 : USE_RUID indicates the first encountered, i.e. last, of these uses.
800 : If ALL_OFFSETS_MATCH is true, all encountered uses were inside a PLUS
801 : with a constant offset; OFFSET contains this constant in that case.
802 : STORE_RUID is always meaningful if we only want to use a value in a
803 : register in a different place: it denotes the next insn in the insn
804 : stream (i.e. the last encountered) that sets or clobbers the register.
805 : REAL_STORE_RUID is similar, but clobbers are ignored when updating it.
806 : EXPR is the expression used when storing the register. */
807 : static struct
808 : {
809 : struct reg_use reg_use[RELOAD_COMBINE_MAX_USES];
810 : rtx offset;
811 : int use_index;
812 : int store_ruid;
813 : int real_store_ruid;
814 : int use_ruid;
815 : bool all_offsets_match;
816 : rtx expr;
817 : } reg_state[FIRST_PSEUDO_REGISTER];
818 :
819 : /* Reverse linear uid. This is increased in reload_combine while scanning
820 : the instructions from last to first. It is used to set last_label_ruid
821 : and the store_ruid / use_ruid fields in reg_state. */
822 : static int reload_combine_ruid;
823 :
824 : /* The RUID of the last label we encountered in reload_combine. */
825 : static int last_label_ruid;
826 :
827 : /* The RUID of the last jump we encountered in reload_combine. */
828 : static int last_jump_ruid;
829 :
830 : /* The register numbers of the first and last index register. A value of
831 : -1 in LAST_INDEX_REG indicates that we've previously computed these
832 : values and found no suitable index registers. */
833 : static int first_index_reg = -1;
834 : static int last_index_reg;
835 :
836 : #define LABEL_LIVE(LABEL) \
837 : (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
838 :
839 : /* Subroutine of reload_combine_split_ruids, called to fix up a single
840 : ruid pointed to by *PRUID if it is higher than SPLIT_RUID. */
841 :
842 : static inline void
843 169847 : reload_combine_split_one_ruid (int *pruid, int split_ruid)
844 : {
845 169847 : if (*pruid > split_ruid)
846 6751 : (*pruid)++;
847 : }
848 :
849 : /* Called when we insert a new insn in a position we've already passed in
850 : the scan. Examine all our state, increasing all ruids that are higher
851 : than SPLIT_RUID by one in order to make room for a new insn. */
852 :
853 : static void
854 590 : reload_combine_split_ruids (int split_ruid)
855 : {
856 590 : unsigned i;
857 :
858 590 : reload_combine_split_one_ruid (&reload_combine_ruid, split_ruid);
859 590 : reload_combine_split_one_ruid (&last_label_ruid, split_ruid);
860 590 : reload_combine_split_one_ruid (&last_jump_ruid, split_ruid);
861 :
862 56050 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
863 : {
864 55460 : int j, idx = reg_state[i].use_index;
865 55460 : reload_combine_split_one_ruid (®_state[i].use_ruid, split_ruid);
866 55460 : reload_combine_split_one_ruid (®_state[i].store_ruid, split_ruid);
867 55460 : reload_combine_split_one_ruid (®_state[i].real_store_ruid,
868 : split_ruid);
869 55460 : if (idx < 0)
870 25277 : continue;
871 31880 : for (j = idx; j < RELOAD_COMBINE_MAX_USES; j++)
872 : {
873 2932 : reload_combine_split_one_ruid (®_state[i].reg_use[j].ruid,
874 : split_ruid);
875 : }
876 : }
877 590 : }
878 :
879 : /* Called when we are about to rescan a previously encountered insn with
880 : reload_combine_note_use after modifying some part of it. This clears all
881 : information about uses in that particular insn. */
882 :
883 : static void
884 5148 : reload_combine_purge_insn_uses (rtx_insn *insn)
885 : {
886 5148 : unsigned i;
887 :
888 489060 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
889 : {
890 483912 : int j, k, idx = reg_state[i].use_index;
891 483912 : if (idx < 0)
892 86500 : continue;
893 : j = k = RELOAD_COMBINE_MAX_USES;
894 434038 : while (j-- > idx)
895 : {
896 36626 : if (reg_state[i].reg_use[j].insn != insn)
897 : {
898 30952 : k--;
899 30952 : if (k != j)
900 3365 : reg_state[i].reg_use[k] = reg_state[i].reg_use[j];
901 : }
902 : }
903 397412 : reg_state[i].use_index = k;
904 : }
905 5148 : }
906 :
907 : /* Called when we need to forget about all uses of REGNO after an insn
908 : which is identified by RUID. */
909 :
910 : static void
911 590 : reload_combine_purge_reg_uses_after_ruid (unsigned regno, int ruid)
912 : {
913 590 : int j, k, idx = reg_state[regno].use_index;
914 590 : if (idx < 0)
915 : return;
916 : j = k = RELOAD_COMBINE_MAX_USES;
917 2272 : while (j-- > idx)
918 : {
919 1682 : if (reg_state[regno].reg_use[j].ruid >= ruid)
920 : {
921 692 : k--;
922 692 : if (k != j)
923 562 : reg_state[regno].reg_use[k] = reg_state[regno].reg_use[j];
924 : }
925 : }
926 590 : reg_state[regno].use_index = k;
927 : }
928 :
929 : /* Find the use of REGNO with the ruid that is highest among those
930 : lower than RUID_LIMIT, and return it if it is the only use of this
931 : reg in the insn. Return NULL otherwise. */
932 :
933 : static struct reg_use *
934 3930367 : reload_combine_closest_single_use (unsigned regno, int ruid_limit)
935 : {
936 3930367 : int i, best_ruid = 0;
937 3930367 : int use_idx = reg_state[regno].use_index;
938 3930367 : struct reg_use *retval;
939 :
940 3930367 : if (use_idx < 0)
941 : return NULL;
942 : retval = NULL;
943 3827102 : for (i = use_idx; i < RELOAD_COMBINE_MAX_USES; i++)
944 : {
945 2216290 : struct reg_use *use = reg_state[regno].reg_use + i;
946 2216290 : int this_ruid = use->ruid;
947 2216290 : if (this_ruid >= ruid_limit)
948 819980 : continue;
949 1396310 : if (this_ruid > best_ruid)
950 : {
951 : best_ruid = this_ruid;
952 : retval = use;
953 : }
954 371150 : else if (this_ruid == best_ruid)
955 2216290 : retval = NULL;
956 : }
957 1610812 : if (last_label_ruid >= best_ruid)
958 665909 : return NULL;
959 : return retval;
960 : }
961 :
962 : /* After we've moved an add insn, fix up any debug insns that occur
963 : between the old location of the add and the new location. REG is
964 : the destination register of the add insn; REPLACEMENT is the
965 : SET_SRC of the add. FROM and TO specify the range in which we
966 : should make this change on debug insns. */
967 :
968 : static void
969 759 : fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
970 : {
971 759 : rtx_insn *insn;
972 6136 : for (insn = from; insn != to; insn = NEXT_INSN (insn))
973 : {
974 5377 : rtx t;
975 :
976 5377 : if (!DEBUG_BIND_INSN_P (insn))
977 4199 : continue;
978 :
979 1178 : t = INSN_VAR_LOCATION_LOC (insn);
980 1178 : t = simplify_replace_rtx (t, reg, replacement);
981 1178 : validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0);
982 : }
983 759 : }
984 :
985 : /* Subroutine of reload_combine_recognize_const_pattern. Try to replace REG
986 : with SRC in the insn described by USE, taking costs into account. Return
987 : true if we made the replacement. */
988 :
989 : static bool
990 807052 : try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
991 : {
992 807052 : rtx_insn *use_insn = use->insn;
993 807052 : rtx mem = use->containing_mem;
994 807052 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
995 :
996 807052 : if (mem != NULL_RTX)
997 : {
998 14096 : addr_space_t as = MEM_ADDR_SPACE (mem);
999 14096 : rtx oldaddr = XEXP (mem, 0);
1000 14096 : rtx newaddr = NULL_RTX;
1001 14096 : int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed);
1002 14096 : int new_cost;
1003 :
1004 14096 : newaddr = simplify_replace_rtx (oldaddr, reg, src);
1005 14096 : if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as))
1006 : {
1007 4712 : XEXP (mem, 0) = newaddr;
1008 4712 : new_cost = address_cost (newaddr, GET_MODE (mem), as, speed);
1009 4712 : XEXP (mem, 0) = oldaddr;
1010 4712 : if (new_cost <= old_cost
1011 4712 : && validate_change (use_insn,
1012 : &XEXP (mem, 0), newaddr, 0))
1013 : return true;
1014 : }
1015 : }
1016 : else
1017 : {
1018 792956 : rtx new_set = single_set (use_insn);
1019 792956 : if (new_set
1020 791975 : && REG_P (SET_DEST (new_set))
1021 330386 : && GET_CODE (SET_SRC (new_set)) == PLUS
1022 21562 : && REG_P (XEXP (SET_SRC (new_set), 0))
1023 19498 : && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
1024 : {
1025 1608 : rtx new_src;
1026 1608 : machine_mode mode = GET_MODE (SET_DEST (new_set));
1027 1608 : int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
1028 :
1029 1608 : gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
1030 1608 : new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
1031 :
1032 1608 : if (set_src_cost (new_src, mode, speed) <= old_cost
1033 1608 : && validate_change (use_insn, &SET_SRC (new_set),
1034 : new_src, 0))
1035 : return true;
1036 : }
1037 : }
1038 : return false;
1039 : }
1040 :
1041 : /* Called by reload_combine when scanning INSN. This function tries to detect
1042 : patterns where a constant is added to a register, and the result is used
1043 : in an address.
1044 : Return true if no further processing is needed on INSN; false if it wasn't
1045 : recognized and should be handled normally. */
1046 :
1047 : static bool
1048 62968008 : reload_combine_recognize_const_pattern (rtx_insn *insn)
1049 : {
1050 62968008 : int from_ruid = reload_combine_ruid;
1051 62968008 : rtx set, pat, reg, src, addreg;
1052 62968008 : unsigned int regno;
1053 62968008 : struct reg_use *use;
1054 62968008 : bool must_move_add;
1055 62968008 : rtx_insn *add_moved_after_insn = NULL;
1056 62968008 : int add_moved_after_ruid = 0;
1057 62968008 : int clobbered_regno = -1;
1058 :
1059 62968008 : set = single_set (insn);
1060 62968008 : if (set == NULL_RTX)
1061 : return false;
1062 :
1063 58700139 : reg = SET_DEST (set);
1064 58700139 : src = SET_SRC (set);
1065 58700139 : if (!REG_P (reg)
1066 40068221 : || REG_NREGS (reg) != 1
1067 45670493 : || GET_MODE (reg) != Pmode
1068 81662297 : || reg == stack_pointer_rtx)
1069 : return false;
1070 :
1071 21270275 : regno = REGNO (reg);
1072 :
1073 : /* We look for a REG1 = REG2 + CONSTANT insn, followed by either
1074 : uses of REG1 inside an address, or inside another add insn. If
1075 : possible and profitable, merge the addition into subsequent
1076 : uses. */
1077 21270275 : if (GET_CODE (src) != PLUS
1078 4172125 : || !REG_P (XEXP (src, 0))
1079 3915212 : || !CONSTANT_P (XEXP (src, 1)))
1080 : return false;
1081 :
1082 3237654 : addreg = XEXP (src, 0);
1083 3237654 : must_move_add = rtx_equal_p (reg, addreg);
1084 :
1085 3237654 : pat = PATTERN (insn);
1086 3237654 : if (must_move_add && set != pat)
1087 : {
1088 : /* We have to be careful when moving the add; apart from the
1089 : single_set there may also be clobbers. Recognize one special
1090 : case, that of one clobber alongside the set (likely a clobber
1091 : of the CC register). */
1092 877686 : gcc_assert (GET_CODE (PATTERN (insn)) == PARALLEL);
1093 877686 : if (XVECLEN (pat, 0) != 2 || XVECEXP (pat, 0, 0) != set
1094 877686 : || GET_CODE (XVECEXP (pat, 0, 1)) != CLOBBER
1095 877686 : || !REG_P (XEXP (XVECEXP (pat, 0, 1), 0)))
1096 : return false;
1097 877686 : clobbered_regno = REGNO (XEXP (XVECEXP (pat, 0, 1), 0));
1098 : }
1099 :
1100 3930367 : do
1101 : {
1102 3930367 : use = reload_combine_closest_single_use (regno, from_ruid);
1103 :
1104 3930367 : if (use)
1105 : /* Start the search for the next use from here. */
1106 921909 : from_ruid = use->ruid;
1107 :
1108 1277372 : if (use && GET_MODE (*use->usep) == Pmode)
1109 : {
1110 915681 : bool delete_add = false;
1111 915681 : rtx_insn *use_insn = use->insn;
1112 915681 : int use_ruid = use->ruid;
1113 :
1114 : /* Avoid moving the add insn past a jump. */
1115 915681 : if (must_move_add && use_ruid <= last_jump_ruid)
1116 : break;
1117 :
1118 : /* If the add clobbers another hard reg in parallel, don't move
1119 : it past a real set of this hard reg. */
1120 915450 : if (must_move_add && clobbered_regno >= 0
1121 145034 : && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1122 : break;
1123 :
1124 878006 : gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1125 : /* Avoid moving a use of ADDREG past a point where it is stored. */
1126 878006 : if (reg_state[REGNO (addreg)].store_ruid > use_ruid)
1127 : break;
1128 :
1129 : /* We also must not move the addition past an insn that sets
1130 : the same register, unless we can combine two add insns. */
1131 807058 : if (must_move_add && reg_state[regno].store_ruid == use_ruid)
1132 : {
1133 30843 : if (use->containing_mem == NULL_RTX)
1134 : delete_add = true;
1135 : else
1136 : break;
1137 : }
1138 :
1139 807052 : if (try_replace_in_use (use, reg, src))
1140 : {
1141 5148 : reload_combine_purge_insn_uses (use_insn);
1142 5148 : reload_combine_note_use (&PATTERN (use_insn), use_insn,
1143 : use_ruid, NULL_RTX);
1144 :
1145 5148 : if (delete_add)
1146 : {
1147 53 : fixup_debug_insns (reg, src, insn, use_insn);
1148 53 : delete_insn (insn);
1149 53 : return true;
1150 : }
1151 5095 : if (must_move_add)
1152 : {
1153 966 : add_moved_after_insn = use_insn;
1154 966 : add_moved_after_ruid = use_ruid;
1155 : }
1156 5095 : continue;
1157 : }
1158 : }
1159 : /* If we get here, we couldn't handle this use. */
1160 3816590 : if (must_move_add)
1161 : break;
1162 : }
1163 2949523 : while (use);
1164 :
1165 3237601 : if (!must_move_add || add_moved_after_insn == NULL_RTX)
1166 : /* Process the add normally. */
1167 : return false;
1168 :
1169 590 : fixup_debug_insns (reg, src, insn, add_moved_after_insn);
1170 :
1171 590 : reorder_insns (insn, insn, add_moved_after_insn);
1172 590 : reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
1173 590 : reload_combine_split_ruids (add_moved_after_ruid - 1);
1174 590 : reload_combine_note_use (&PATTERN (insn), insn,
1175 : add_moved_after_ruid, NULL_RTX);
1176 590 : reg_state[regno].store_ruid = add_moved_after_ruid;
1177 :
1178 590 : return true;
1179 : }
1180 :
1181 : /* Called by reload_combine when scanning INSN. Try to detect a pattern we
1182 : can handle and improve. Return true if no further processing is needed on
1183 : INSN; false if it wasn't recognized and should be handled normally. */
1184 :
1185 : static bool
1186 62967365 : reload_combine_recognize_pattern (rtx_insn *insn)
1187 : {
1188 62967365 : rtx set, reg, src;
1189 :
1190 62967365 : set = single_set (insn);
1191 62967365 : if (set == NULL_RTX)
1192 : return false;
1193 :
1194 58699496 : reg = SET_DEST (set);
1195 58699496 : src = SET_SRC (set);
1196 58699496 : if (!REG_P (reg) || REG_NREGS (reg) != 1)
1197 : return false;
1198 :
1199 39354080 : unsigned int regno = REGNO (reg);
1200 39354080 : machine_mode mode = GET_MODE (reg);
1201 :
1202 39354080 : if (reg_state[regno].use_index < 0
1203 39354080 : || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1204 : return false;
1205 :
1206 25371923 : for (int i = reg_state[regno].use_index;
1207 46428582 : i < RELOAD_COMBINE_MAX_USES; i++)
1208 : {
1209 26200570 : struct reg_use *use = reg_state[regno].reg_use + i;
1210 26200570 : if (GET_MODE (*use->usep) != mode)
1211 : return false;
1212 : /* Don't try to adjust (use (REGX)). */
1213 25375632 : if (GET_CODE (PATTERN (use->insn)) == USE
1214 25375632 : && &XEXP (PATTERN (use->insn), 0) == use->usep)
1215 : return false;
1216 : }
1217 :
1218 : /* Look for (set (REGX) (CONST_INT))
1219 : (set (REGX) (PLUS (REGX) (REGY)))
1220 : ...
1221 : ... (MEM (REGX)) ...
1222 : and convert it to
1223 : (set (REGZ) (CONST_INT))
1224 : ...
1225 : ... (MEM (PLUS (REGZ) (REGY)))... .
1226 :
1227 : First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
1228 : and that we know all uses of REGX before it dies.
1229 : Also, explicitly check that REGX != REGY; our life information
1230 : does not yet show whether REGY changes in this insn. */
1231 :
1232 20228012 : if (GET_CODE (src) == PLUS
1233 2416970 : && reg_state[regno].all_offsets_match
1234 2153970 : && last_index_reg != -1
1235 2153970 : && REG_P (XEXP (src, 1))
1236 720231 : && rtx_equal_p (XEXP (src, 0), reg)
1237 524505 : && !rtx_equal_p (XEXP (src, 1), reg)
1238 20744181 : && last_label_ruid < reg_state[regno].use_ruid)
1239 : {
1240 483507 : rtx base = XEXP (src, 1);
1241 483507 : rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1242 483507 : rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1243 483507 : rtx index_reg = NULL_RTX;
1244 483507 : rtx reg_sum = NULL_RTX;
1245 483507 : int i;
1246 :
1247 : /* Now we need to set INDEX_REG to an index register (denoted as
1248 : REGZ in the illustration above) and REG_SUM to the expression
1249 : register+register that we want to use to substitute uses of REG
1250 : (typically in MEMs) with. First check REG and BASE for being
1251 : index registers; we can use them even if they are not dead. */
1252 483507 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
1253 483507 : || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
1254 : REGNO (base)))
1255 : {
1256 : index_reg = reg;
1257 : reg_sum = src;
1258 : }
1259 : else
1260 : {
1261 : /* Otherwise, look for a free index register. Since we have
1262 : checked above that neither REG nor BASE are index registers,
1263 : if we find anything at all, it will be different from these
1264 : two registers. */
1265 8968089 : for (i = first_index_reg; i <= last_index_reg; i++)
1266 : {
1267 8880357 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
1268 3053337 : && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1269 1755514 : && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1270 1739513 : && (crtl->abi->clobbers_full_reg_p (i)
1271 332902 : || df_regs_ever_live_p (i))
1272 1470443 : && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1273 1469411 : && !fixed_regs[i] && !global_regs[i]
1274 533307 : && hard_regno_nregs (i, GET_MODE (reg)) == 1
1275 9014630 : && targetm.hard_regno_scratch_ok (i))
1276 : {
1277 134273 : index_reg = gen_rtx_REG (GET_MODE (reg), i);
1278 134273 : reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1279 134273 : break;
1280 : }
1281 : }
1282 : }
1283 :
1284 : /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
1285 : (REGY), i.e. BASE, is not clobbered before the last use we'll
1286 : create. */
1287 483507 : if (reg_sum
1288 483507 : && prev_set
1289 389083 : && CONST_INT_P (SET_SRC (prev_set))
1290 9819 : && rtx_equal_p (SET_DEST (prev_set), reg)
1291 483507 : && (reg_state[REGNO (base)].store_ruid
1292 3498 : <= reg_state[regno].use_ruid))
1293 : {
1294 : /* Change destination register and, if necessary, the constant
1295 : value in PREV, the constant loading instruction. */
1296 3389 : validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
1297 3389 : if (reg_state[regno].offset != const0_rtx)
1298 : {
1299 0 : HOST_WIDE_INT c
1300 0 : = trunc_int_for_mode (UINTVAL (SET_SRC (prev_set))
1301 0 : + UINTVAL (reg_state[regno].offset),
1302 0 : GET_MODE (index_reg));
1303 0 : validate_change (prev, &SET_SRC (prev_set), GEN_INT (c), 1);
1304 : }
1305 :
1306 : /* Now for every use of REG that we have recorded, replace REG
1307 : with REG_SUM. */
1308 6854 : for (i = reg_state[regno].use_index;
1309 6854 : i < RELOAD_COMBINE_MAX_USES; i++)
1310 3465 : validate_unshare_change (reg_state[regno].reg_use[i].insn,
1311 : reg_state[regno].reg_use[i].usep,
1312 : /* Each change must have its own
1313 : replacement. */
1314 : reg_sum, 1);
1315 :
1316 3389 : if (apply_change_group ())
1317 : {
1318 116 : struct reg_use *lowest_ruid = NULL;
1319 :
1320 : /* For every new use of REG_SUM, we have to record the use
1321 : of BASE therein, i.e. operand 1. */
1322 252 : for (i = reg_state[regno].use_index;
1323 252 : i < RELOAD_COMBINE_MAX_USES; i++)
1324 : {
1325 136 : struct reg_use *use = reg_state[regno].reg_use + i;
1326 136 : reload_combine_note_use (&XEXP (*use->usep, 1), use->insn,
1327 : use->ruid, use->containing_mem);
1328 136 : if (lowest_ruid == NULL || use->ruid < lowest_ruid->ruid)
1329 136 : lowest_ruid = use;
1330 : }
1331 :
1332 116 : fixup_debug_insns (reg, reg_sum, insn, lowest_ruid->insn);
1333 :
1334 : /* Delete the reg-reg addition. */
1335 116 : delete_insn (insn);
1336 :
1337 116 : if (reg_state[regno].offset != const0_rtx)
1338 : /* Previous REG_EQUIV / REG_EQUAL notes for PREV
1339 : are now invalid. */
1340 0 : remove_reg_equal_equiv_notes (prev);
1341 :
1342 116 : reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
1343 116 : return true;
1344 : }
1345 : }
1346 : }
1347 : return false;
1348 : }
1349 :
1350 : static void
1351 1076450 : reload_combine (void)
1352 : {
1353 1076450 : rtx_insn *insn, *prev;
1354 1076450 : basic_block bb;
1355 1076450 : unsigned int r;
1356 1076450 : int min_labelno, n_labels;
1357 1076450 : HARD_REG_SET ever_live_at_start, *label_live;
1358 :
1359 : /* To avoid wasting too much time later searching for an index register,
1360 : determine the minimum and maximum index register numbers. */
1361 1076450 : if (INDEX_REG_CLASS == NO_REGS)
1362 : last_index_reg = -1;
1363 1076450 : else if (first_index_reg == -1 && last_index_reg == 0)
1364 : {
1365 148008 : hard_reg_set_iterator hrsi1;
1366 4736256 : EXECUTE_IF_SET_IN_HARD_REG_SET
1367 : (reg_class_contents[INDEX_REG_CLASS], 0, r, hrsi1)
1368 : {
1369 4588248 : if (first_index_reg == -1)
1370 148008 : first_index_reg = r;
1371 :
1372 4588248 : last_index_reg = r;
1373 : }
1374 :
1375 : /* If no index register is available, we can quit now. Set LAST_INDEX_REG
1376 : to -1 so we'll know to quit early the next time we get here. */
1377 148008 : if (first_index_reg == -1)
1378 : {
1379 0 : last_index_reg = -1;
1380 0 : return;
1381 : }
1382 : }
1383 :
1384 : /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
1385 : information is a bit fuzzy immediately after reload, but it's
1386 : still good enough to determine which registers are live at a jump
1387 : destination. */
1388 1076450 : min_labelno = get_first_label_num ();
1389 1076450 : n_labels = max_label_num () - min_labelno;
1390 1076450 : label_live = XNEWVEC (HARD_REG_SET, n_labels);
1391 1076450 : CLEAR_HARD_REG_SET (ever_live_at_start);
1392 :
1393 12967476 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
1394 : {
1395 11891026 : insn = BB_HEAD (bb);
1396 11891026 : if (LABEL_P (insn))
1397 : {
1398 5551707 : HARD_REG_SET live;
1399 5551707 : bitmap live_in = df_get_live_in (bb);
1400 :
1401 11103414 : REG_SET_TO_HARD_REG_SET (live, live_in);
1402 5551707 : compute_use_by_pseudos (&live, live_in);
1403 5551707 : LABEL_LIVE (insn) = live;
1404 11103414 : ever_live_at_start |= live;
1405 : }
1406 : }
1407 :
1408 : /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
1409 1076450 : last_label_ruid = last_jump_ruid = reload_combine_ruid = 0;
1410 102262750 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1411 : {
1412 101186300 : reg_state[r].store_ruid = 0;
1413 101186300 : reg_state[r].real_store_ruid = 0;
1414 101186300 : if (fixed_regs[r])
1415 : reg_state[r].use_index = -1;
1416 : else
1417 50042873 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1418 : }
1419 :
1420 152313461 : for (insn = get_last_insn (); insn; insn = prev)
1421 : {
1422 151237011 : bool control_flow_insn;
1423 151237011 : rtx note;
1424 :
1425 151237011 : prev = PREV_INSN (insn);
1426 :
1427 : /* We cannot do our optimization across labels. Invalidating all the use
1428 : information we have would be costly, so we just note where the label
1429 : is and then later disable any optimization that would cross it. */
1430 151237011 : if (LABEL_P (insn))
1431 5559197 : last_label_ruid = reload_combine_ruid;
1432 145677814 : else if (BARRIER_P (insn))
1433 : {
1434 : /* Crossing a barrier resets all the use information. */
1435 304492670 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1436 301287484 : if (! fixed_regs[r])
1437 144094816 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1438 : }
1439 142472628 : else if (INSN_P (insn) && volatile_insn_p (PATTERN (insn)))
1440 : /* Optimizations across insns being marked as volatile must be
1441 : prevented. All the usage information is invalidated
1442 : here. */
1443 42430990 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1444 41984348 : if (! fixed_regs[r]
1445 19297392 : && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1446 648016 : reg_state[r].use_index = -1;
1447 :
1448 151237011 : if (! NONDEBUG_INSN_P (insn))
1449 88269003 : continue;
1450 :
1451 62968008 : reload_combine_ruid++;
1452 :
1453 62968008 : control_flow_insn = control_flow_insn_p (insn);
1454 62968008 : if (control_flow_insn)
1455 9117021 : last_jump_ruid = reload_combine_ruid;
1456 :
1457 62968008 : if (reload_combine_recognize_const_pattern (insn)
1458 62968008 : || reload_combine_recognize_pattern (insn))
1459 759 : continue;
1460 :
1461 62967249 : note_stores (insn, reload_combine_note_store, NULL);
1462 :
1463 62967249 : if (CALL_P (insn))
1464 : {
1465 5039645 : rtx link;
1466 5039645 : HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
1467 :
1468 5039645 : hard_reg_set_iterator hrsi2;
1469 426794290 : EXECUTE_IF_SET_IN_HARD_REG_SET (used_regs, 0, r, hrsi2)
1470 : {
1471 421754645 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1472 421754645 : reg_state[r].store_ruid = reload_combine_ruid;
1473 : }
1474 :
1475 15191493 : for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1476 10151848 : link = XEXP (link, 1))
1477 : {
1478 10151848 : rtx setuse = XEXP (link, 0);
1479 10151848 : rtx usage_rtx = XEXP (setuse, 0);
1480 :
1481 10151848 : if (GET_CODE (setuse) == USE && REG_P (usage_rtx))
1482 : {
1483 9173708 : unsigned int end_regno = END_REGNO (usage_rtx);
1484 18404955 : for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1485 9231247 : reg_state[i].use_index = -1;
1486 : }
1487 : }
1488 : }
1489 :
1490 62967249 : if (control_flow_insn && !ANY_RETURN_P (PATTERN (insn)))
1491 : {
1492 : /* Non-spill registers might be used at the call destination in
1493 : some unknown fashion, so we have to mark the unknown use. */
1494 9117021 : HARD_REG_SET *live;
1495 :
1496 10600703 : if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1497 9117095 : && JUMP_LABEL (insn))
1498 : {
1499 7633413 : if (ANY_RETURN_P (JUMP_LABEL (insn)))
1500 : live = NULL;
1501 : else
1502 7633413 : live = &LABEL_LIVE (JUMP_LABEL (insn));
1503 : }
1504 : else
1505 : live = &ever_live_at_start;
1506 :
1507 7633413 : if (live)
1508 : {
1509 9117021 : hard_reg_set_iterator hrsi3;
1510 55440160 : EXECUTE_IF_SET_IN_HARD_REG_SET (*live, 0, r, hrsi3)
1511 46323139 : reg_state[r].use_index = -1;
1512 : }
1513 : }
1514 :
1515 62967249 : reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1516 : NULL_RTX);
1517 :
1518 87662102 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1519 : {
1520 24694853 : if (REG_NOTE_KIND (note) == REG_INC && REG_P (XEXP (note, 0)))
1521 : {
1522 0 : int regno = REGNO (XEXP (note, 0));
1523 0 : reg_state[regno].store_ruid = reload_combine_ruid;
1524 0 : reg_state[regno].real_store_ruid = reload_combine_ruid;
1525 0 : reg_state[regno].use_index = -1;
1526 : }
1527 : }
1528 : }
1529 :
1530 1076450 : free (label_live);
1531 : }
1532 :
1533 : /* Check if DST is a register or a subreg of a register; if it is,
1534 : update store_ruid, real_store_ruid and use_index in the reg_state
1535 : structure accordingly. Called via note_stores from reload_combine. */
1536 :
1537 : static void
1538 67373715 : reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1539 : {
1540 67373715 : int regno = 0;
1541 67373715 : int i;
1542 67373715 : machine_mode mode = GET_MODE (dst);
1543 :
1544 67373715 : if (GET_CODE (dst) == SUBREG)
1545 : {
1546 5492 : regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1547 2746 : GET_MODE (SUBREG_REG (dst)),
1548 2746 : SUBREG_BYTE (dst),
1549 : GET_MODE (dst));
1550 2746 : dst = SUBREG_REG (dst);
1551 : }
1552 :
1553 : /* Some targets do argument pushes without adding REG_INC notes. */
1554 :
1555 67373715 : if (MEM_P (dst))
1556 : {
1557 11098119 : dst = XEXP (dst, 0);
1558 11098119 : if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1559 11098119 : || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1560 9475774 : || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1561 : {
1562 1692149 : unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1563 3384298 : for (unsigned int i = REGNO (XEXP (dst, 0)); i < end_regno; ++i)
1564 : {
1565 : /* We could probably do better, but for now mark the register
1566 : as used in an unknown fashion and set/clobbered at this
1567 : insn. */
1568 1692149 : reg_state[i].use_index = -1;
1569 1692149 : reg_state[i].store_ruid = reload_combine_ruid;
1570 1692149 : reg_state[i].real_store_ruid = reload_combine_ruid;
1571 : }
1572 : }
1573 : else
1574 : return;
1575 : }
1576 :
1577 57967745 : if (!REG_P (dst))
1578 : return;
1579 48629794 : regno += REGNO (dst);
1580 :
1581 : /* note_stores might have stripped a STRICT_LOW_PART, so we have to be
1582 : careful with registers / register parts that are not full words.
1583 : Similarly for ZERO_EXTRACT. */
1584 48629794 : if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1585 48628623 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1586 : {
1587 9122 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1588 : {
1589 4561 : reg_state[i].use_index = -1;
1590 4561 : reg_state[i].store_ruid = reload_combine_ruid;
1591 4561 : reg_state[i].real_store_ruid = reload_combine_ruid;
1592 : }
1593 : }
1594 : else
1595 : {
1596 97972593 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1597 : {
1598 49347360 : reg_state[i].store_ruid = reload_combine_ruid;
1599 49347360 : if (GET_CODE (set) == SET)
1600 41656026 : reg_state[i].real_store_ruid = reload_combine_ruid;
1601 49347360 : reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
1602 : }
1603 : }
1604 : }
1605 :
1606 : /* XP points to a piece of rtl that has to be checked for any uses of
1607 : registers.
1608 : *XP is the pattern of INSN, or a part of it.
1609 : Called from reload_combine, and recursively by itself. */
1610 : static void
1611 223597792 : reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1612 : {
1613 264520914 : rtx x = *xp;
1614 264520914 : enum rtx_code code = x->code;
1615 264520914 : const char *fmt;
1616 264520914 : int i, j;
1617 264520914 : rtx offset = const0_rtx; /* For the REG case below. */
1618 :
1619 264520914 : switch (code)
1620 : {
1621 59633472 : case SET:
1622 59633472 : if (REG_P (SET_DEST (x)))
1623 : {
1624 40923122 : reload_combine_note_use (&SET_SRC (x), insn, ruid, NULL_RTX);
1625 40923122 : return;
1626 : }
1627 : break;
1628 :
1629 668026 : case USE:
1630 : /* If this is the USE of a return value, we can't change it. */
1631 668026 : if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
1632 : {
1633 : /* Mark the return register as used in an unknown fashion. */
1634 571960 : rtx reg = XEXP (x, 0);
1635 571960 : unsigned int end_regno = END_REGNO (reg);
1636 1172758 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1637 600798 : reg_state[regno].use_index = -1;
1638 : return;
1639 : }
1640 : break;
1641 :
1642 7741309 : case CLOBBER:
1643 7741309 : if (REG_P (SET_DEST (x)))
1644 : {
1645 : /* No spurious CLOBBERs of pseudo registers may remain. */
1646 7689974 : gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1647 : return;
1648 : }
1649 : break;
1650 :
1651 23965886 : case PLUS:
1652 : /* We are interested in (plus (reg) (const_int)) . */
1653 23965886 : if (!REG_P (XEXP (x, 0))
1654 21568447 : || !CONST_INT_P (XEXP (x, 1)))
1655 : break;
1656 : offset = XEXP (x, 1);
1657 : x = XEXP (x, 0);
1658 : /* Fall through. */
1659 61899677 : case REG:
1660 61899677 : {
1661 61899677 : int regno = REGNO (x);
1662 61899677 : int use_index;
1663 61899677 : int nregs;
1664 :
1665 : /* No spurious USEs of pseudo registers may remain. */
1666 61899677 : gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1667 :
1668 61899677 : nregs = REG_NREGS (x);
1669 :
1670 : /* We can't substitute into multi-hard-reg uses. */
1671 61899677 : if (nregs > 1)
1672 : {
1673 1541322 : while (--nregs >= 0)
1674 1027548 : reg_state[regno + nregs].use_index = -1;
1675 : return;
1676 : }
1677 :
1678 : /* We may be called to update uses in previously seen insns.
1679 : Don't add uses beyond the last store we saw. */
1680 61385903 : if (ruid < reg_state[regno].store_ruid)
1681 : return;
1682 :
1683 : /* If this register is already used in some unknown fashion, we
1684 : can't do anything.
1685 : If we decrement the index from zero to -1, we can't store more
1686 : uses, so this register becomes used in an unknown fashion. */
1687 61384694 : use_index = --reg_state[regno].use_index;
1688 61384694 : if (use_index < 0)
1689 : return;
1690 :
1691 37011754 : if (use_index == RELOAD_COMBINE_MAX_USES - 1)
1692 : {
1693 : /* This is the first use of this register we have seen since we
1694 : marked it as dead. */
1695 28076203 : reg_state[regno].offset = offset;
1696 28076203 : reg_state[regno].all_offsets_match = true;
1697 28076203 : reg_state[regno].use_ruid = ruid;
1698 : }
1699 : else
1700 : {
1701 8935551 : if (reg_state[regno].use_ruid > ruid)
1702 322 : reg_state[regno].use_ruid = ruid;
1703 :
1704 8935551 : if (! rtx_equal_p (offset, reg_state[regno].offset))
1705 3982402 : reg_state[regno].all_offsets_match = false;
1706 : }
1707 :
1708 37011754 : reg_state[regno].reg_use[use_index].insn = insn;
1709 37011754 : reg_state[regno].reg_use[use_index].ruid = ruid;
1710 37011754 : reg_state[regno].reg_use[use_index].containing_mem = containing_mem;
1711 37011754 : reg_state[regno].reg_use[use_index].usep = xp;
1712 37011754 : return;
1713 : }
1714 :
1715 : case MEM:
1716 153436181 : containing_mem = x;
1717 : break;
1718 :
1719 : default:
1720 : break;
1721 : }
1722 :
1723 : /* Recursively process the components of X. */
1724 153436181 : fmt = GET_RTX_FORMAT (code);
1725 392082012 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1726 : {
1727 238645831 : if (fmt[i] == 'e')
1728 139710680 : reload_combine_note_use (&XEXP (x, i), insn, ruid, containing_mem);
1729 98935151 : else if (fmt[i] == 'E')
1730 : {
1731 30999351 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1732 20913989 : reload_combine_note_use (&XVECEXP (x, i, j), insn, ruid,
1733 : containing_mem);
1734 : }
1735 : }
1736 : }
1737 :
1738 : /* See if we can reduce the cost of a constant by replacing a move
1739 : with an add. We track situations in which a register is set to a
1740 : constant or to a register plus a constant. */
1741 : /* We cannot do our optimization across labels. Invalidating all the
1742 : information about register contents we have would be costly, so we
1743 : use move2add_last_label_luid to note where the label is and then
1744 : later disable any optimization that would cross it.
1745 : reg_offset[n] / reg_base_reg[n] / reg_symbol_ref[n] / reg_mode[n]
1746 : are only valid if reg_set_luid[n] is greater than
1747 : move2add_last_label_luid.
1748 : For a set that established a new (potential) base register with
1749 : non-constant value, we use move2add_luid from the place where the
1750 : setting insn is encountered; registers based off that base then
1751 : get the same reg_set_luid. Constants all get
1752 : move2add_last_label_luid + 1 as their reg_set_luid. */
1753 : static int reg_set_luid[FIRST_PSEUDO_REGISTER];
1754 :
1755 : /* If reg_base_reg[n] is negative, register n has been set to
1756 : reg_offset[n] or reg_symbol_ref[n] + reg_offset[n] in mode reg_mode[n].
1757 : If reg_base_reg[n] is non-negative, register n has been set to the
1758 : sum of reg_offset[n] and the value of register reg_base_reg[n]
1759 : before reg_set_luid[n], calculated in mode reg_mode[n] .
1760 : For multi-hard-register registers, all but the first one are
1761 : recorded as BLKmode in reg_mode. Setting reg_mode to VOIDmode
1762 : marks it as invalid. */
1763 : static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
1764 : static int reg_base_reg[FIRST_PSEUDO_REGISTER];
1765 : static rtx reg_symbol_ref[FIRST_PSEUDO_REGISTER];
1766 : static machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
1767 :
1768 : /* move2add_luid is linearly increased while scanning the instructions
1769 : from first to last. It is used to set reg_set_luid in
1770 : reload_cse_move2add and move2add_note_store. */
1771 : static int move2add_luid;
1772 :
1773 : /* move2add_last_label_luid is set whenever a label is found. Labels
1774 : invalidate all previously collected reg_offset data. */
1775 : static int move2add_last_label_luid;
1776 :
1777 : /* ??? We don't know how zero / sign extension is handled, hence we
1778 : can't go from a narrower to a wider mode. */
1779 : #define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
1780 : (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
1781 : || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
1782 : && TRULY_NOOP_TRUNCATION_MODES_P (OUTMODE, INMODE)))
1783 :
1784 : /* Record that REG is being set to a value with the mode of REG. */
1785 :
1786 : static void
1787 54631518 : move2add_record_mode (rtx reg)
1788 : {
1789 54631518 : int regno, nregs;
1790 54631518 : machine_mode mode = GET_MODE (reg);
1791 :
1792 54631518 : if (GET_CODE (reg) == SUBREG)
1793 : {
1794 2688 : regno = subreg_regno (reg);
1795 2688 : nregs = subreg_nregs (reg);
1796 : }
1797 54628830 : else if (REG_P (reg))
1798 : {
1799 54628830 : regno = REGNO (reg);
1800 54628830 : nregs = REG_NREGS (reg);
1801 : }
1802 : else
1803 0 : gcc_unreachable ();
1804 55332996 : for (int i = nregs - 1; i > 0; i--)
1805 701478 : reg_mode[regno + i] = BLKmode;
1806 54631518 : reg_mode[regno] = mode;
1807 54631518 : }
1808 :
1809 : /* Record that REG is being set to the sum of SYM and OFF. */
1810 :
1811 : static void
1812 2210222 : move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1813 : {
1814 2210222 : int regno = REGNO (reg);
1815 :
1816 2210222 : move2add_record_mode (reg);
1817 2210222 : reg_set_luid[regno] = move2add_luid;
1818 2210222 : reg_base_reg[regno] = -1;
1819 2210222 : reg_symbol_ref[regno] = sym;
1820 2210222 : reg_offset[regno] = INTVAL (off);
1821 2210222 : }
1822 :
1823 : /* Check if REGNO contains a valid value in MODE. */
1824 :
1825 : static bool
1826 225629188 : move2add_valid_value_p (int regno, scalar_int_mode mode)
1827 : {
1828 225629188 : if (reg_set_luid[regno] <= move2add_last_label_luid)
1829 : return false;
1830 :
1831 22517659 : if (mode != reg_mode[regno])
1832 : {
1833 12115884 : scalar_int_mode old_mode;
1834 12115884 : if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1835 17798592 : || !MODES_OK_FOR_MOVE2ADD (mode, old_mode)
1836 549799 : || !REG_CAN_CHANGE_MODE_P (regno, old_mode, mode))
1837 225629188 : return false;
1838 : /* The value loaded into regno in reg_mode[regno] is also valid in
1839 : mode after truncation only if (REG:mode regno) is the lowpart of
1840 : (REG:reg_mode[regno] regno). Now, for big endian, the starting
1841 : regno of the lowpart might be different. */
1842 549799 : poly_int64 s_off = subreg_lowpart_offset (mode, old_mode);
1843 549799 : s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1844 549799 : if (maybe_ne (s_off, 0))
1845 : /* We could in principle adjust regno, check reg_mode[regno] to be
1846 : BLKmode, and return s_off to the caller (vs. -1 for failure),
1847 : but we currently have no callers that could make use of this
1848 : information. */
1849 : return false;
1850 : }
1851 :
1852 11014969 : for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1853 69396 : if (reg_mode[i] != BLKmode)
1854 : return false;
1855 : return true;
1856 : }
1857 :
1858 : /* This function is called with INSN that sets REG (of mode MODE)
1859 : to (SYM + OFF), while REG is known to already have value (SYM + offset).
1860 : This function tries to change INSN into an add instruction
1861 : (set (REG) (plus (REG) (OFF - offset))) using the known value.
1862 : It also updates the information about REG's known value.
1863 : Return true if we made a change. */
1864 :
1865 : static bool
1866 149799 : move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1867 : rtx_insn *insn)
1868 : {
1869 149799 : rtx set = single_set (insn);
1870 149799 : rtx src = SET_SRC (set);
1871 149799 : int regno = REGNO (reg);
1872 149799 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1873 149799 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1874 149799 : bool changed = false;
1875 :
1876 : /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1877 : use (set (reg) (reg)) instead.
1878 : We don't delete this insn, nor do we convert it into a
1879 : note, to avoid losing register notes or the return
1880 : value flag. jump2 already knows how to get rid of
1881 : no-op moves. */
1882 149799 : if (new_src == const0_rtx)
1883 : {
1884 : /* If the constants are different, this is a
1885 : truncation, that, if turned into (set (reg)
1886 : (reg)), would be discarded. Maybe we should
1887 : try a truncMN pattern? */
1888 12493 : if (INTVAL (off) == reg_offset [regno])
1889 10240 : changed = validate_change (insn, &SET_SRC (set), reg, 0);
1890 : }
1891 : else
1892 : {
1893 137306 : struct full_rtx_costs oldcst, newcst;
1894 137306 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1895 :
1896 137306 : get_full_set_rtx_cost (set, &oldcst);
1897 137306 : SET_SRC (set) = tem;
1898 137306 : get_full_set_rtx_cost (set, &newcst);
1899 137306 : SET_SRC (set) = src;
1900 :
1901 137306 : if (costs_lt_p (&newcst, &oldcst, speed)
1902 137306 : && have_add2_insn (reg, new_src))
1903 3719 : changed = validate_change (insn, &SET_SRC (set), tem, 0);
1904 133587 : else if (sym == NULL_RTX && mode != BImode)
1905 : {
1906 131661 : scalar_int_mode narrow_mode;
1907 447651 : FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1908 : {
1909 315990 : if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1910 315990 : && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1911 232963 : == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1912 : {
1913 94267 : rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1914 94267 : rtx narrow_src = gen_int_mode (INTVAL (off),
1915 : narrow_mode);
1916 94267 : rtx new_set
1917 94267 : = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1918 : narrow_reg),
1919 : narrow_src);
1920 94267 : get_full_set_rtx_cost (new_set, &newcst);
1921 :
1922 : /* We perform this replacement only if NEXT is either a
1923 : naked SET, or else its single_set is the first element
1924 : in a PARALLEL. */
1925 94267 : rtx *setloc = GET_CODE (PATTERN (insn)) == PARALLEL
1926 94267 : ? &XVECEXP (PATTERN (insn), 0, 0) : &PATTERN (insn);
1927 94267 : if (*setloc == set && costs_lt_p (&newcst, &oldcst, speed))
1928 : {
1929 0 : changed = validate_change (insn, setloc, new_set, 0);
1930 0 : if (changed)
1931 : break;
1932 : }
1933 : }
1934 : }
1935 : }
1936 : }
1937 149799 : move2add_record_sym_value (reg, sym, off);
1938 149799 : return changed;
1939 : }
1940 :
1941 :
1942 : /* This function is called with INSN that sets REG (of mode MODE) to
1943 : (SYM + OFF), but REG doesn't have known value (SYM + offset). This
1944 : function tries to find another register which is known to already have
1945 : value (SYM + offset) and change INSN into an add instruction
1946 : (set (REG) (plus (the found register) (OFF - offset))) if such
1947 : a register is found. It also updates the information about
1948 : REG's known value.
1949 : Return true iff we made a change. */
1950 :
1951 : static bool
1952 1960607 : move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1953 : rtx_insn *insn)
1954 : {
1955 1960607 : rtx set = single_set (insn);
1956 1960607 : rtx src = SET_SRC (set);
1957 1960607 : int regno = REGNO (reg);
1958 : int min_regno = 0;
1959 1960607 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1960 1960607 : int i;
1961 1960607 : bool changed = false;
1962 1960607 : struct full_rtx_costs oldcst, newcst, mincst;
1963 1960607 : rtx plus_expr;
1964 :
1965 1960607 : init_costs_to_max (&mincst);
1966 1960607 : get_full_set_rtx_cost (set, &oldcst);
1967 :
1968 1960607 : plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1969 1960607 : SET_SRC (set) = plus_expr;
1970 :
1971 186257234 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1972 184296633 : if (move2add_valid_value_p (i, mode)
1973 3899091 : && reg_base_reg[i] < 0
1974 1530648 : && reg_symbol_ref[i] != NULL_RTX
1975 185339831 : && rtx_equal_p (sym, reg_symbol_ref[i]))
1976 : {
1977 39052 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1978 19526 : GET_MODE (reg));
1979 : /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1980 : use (set (reg) (reg)) instead.
1981 : We don't delete this insn, nor do we convert it into a
1982 : note, to avoid losing register notes or the return
1983 : value flag. jump2 already knows how to get rid of
1984 : no-op moves. */
1985 19526 : if (new_src == const0_rtx)
1986 : {
1987 6 : init_costs_to_zero (&mincst);
1988 6 : min_regno = i;
1989 6 : break;
1990 : }
1991 : else
1992 : {
1993 19520 : XEXP (plus_expr, 1) = new_src;
1994 19520 : get_full_set_rtx_cost (set, &newcst);
1995 :
1996 19520 : if (costs_lt_p (&newcst, &mincst, speed))
1997 : {
1998 18975 : mincst = newcst;
1999 18975 : min_regno = i;
2000 : }
2001 : }
2002 : }
2003 1960607 : SET_SRC (set) = src;
2004 :
2005 1960607 : if (costs_lt_p (&mincst, &oldcst, speed))
2006 : {
2007 46 : rtx tem;
2008 :
2009 46 : tem = gen_rtx_REG (GET_MODE (reg), min_regno);
2010 46 : if (i != min_regno)
2011 : {
2012 80 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[min_regno],
2013 40 : GET_MODE (reg));
2014 40 : tem = gen_rtx_PLUS (GET_MODE (reg), tem, new_src);
2015 : }
2016 46 : if (validate_change (insn, &SET_SRC (set), tem, 0))
2017 1960607 : changed = true;
2018 : }
2019 1960607 : reg_set_luid[regno] = move2add_luid;
2020 1960607 : move2add_record_sym_value (reg, sym, off);
2021 1960607 : return changed;
2022 : }
2023 :
2024 : /* Perform any invalidations necessary for INSN. */
2025 :
2026 : static void
2027 112648533 : reload_cse_move2add_invalidate (rtx_insn *insn)
2028 : {
2029 135998406 : for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
2030 : {
2031 23349873 : if (REG_NOTE_KIND (note) == REG_INC
2032 0 : && REG_P (XEXP (note, 0)))
2033 : {
2034 : /* Reset the information about this register. */
2035 0 : int regno = REGNO (XEXP (note, 0));
2036 0 : if (regno < FIRST_PSEUDO_REGISTER)
2037 : {
2038 0 : move2add_record_mode (XEXP (note, 0));
2039 0 : reg_mode[regno] = VOIDmode;
2040 : }
2041 : }
2042 : }
2043 :
2044 : /* There are no REG_INC notes for SP autoinc. */
2045 112648533 : subrtx_var_iterator::array_type array;
2046 569131212 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
2047 : {
2048 456482679 : rtx mem = *iter;
2049 456482679 : if (mem
2050 456482679 : && MEM_P (mem)
2051 28658670 : && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
2052 : {
2053 1677284 : if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
2054 1677284 : reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
2055 : }
2056 : }
2057 :
2058 112648533 : note_stores (insn, move2add_note_store, insn);
2059 :
2060 : /* If INSN is a conditional branch, we try to extract an
2061 : implicit set out of it. */
2062 112648533 : if (any_condjump_p (insn))
2063 : {
2064 4926536 : rtx cnd = fis_get_condition (insn);
2065 :
2066 4926536 : if (cnd != NULL_RTX
2067 4414747 : && GET_CODE (cnd) == NE
2068 1980584 : && REG_P (XEXP (cnd, 0))
2069 1322287 : && !reg_set_p (XEXP (cnd, 0), insn)
2070 : /* The following two checks, which are also in
2071 : move2add_note_store, are intended to reduce the
2072 : number of calls to gen_rtx_SET to avoid memory
2073 : allocation if possible. */
2074 1322287 : && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2075 1322286 : && REG_NREGS (XEXP (cnd, 0)) == 1
2076 6248822 : && CONST_INT_P (XEXP (cnd, 1)))
2077 : {
2078 888775 : rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2079 888775 : move2add_note_store (SET_DEST (implicit_set), implicit_set, insn);
2080 : }
2081 : }
2082 :
2083 : /* If this is a CALL_INSN, all call used registers are stored with
2084 : unknown values. */
2085 112648533 : if (CALL_P (insn))
2086 : {
2087 4852747 : function_abi callee_abi = insn_callee_abi (insn);
2088 465863712 : for (int i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2089 456158218 : if (reg_mode[i] != VOIDmode
2090 23110667 : && reg_mode[i] != BLKmode
2091 478709935 : && callee_abi.clobbers_reg_p (reg_mode[i], i))
2092 : /* Reset the information about this register. */
2093 8477273 : reg_mode[i] = VOIDmode;
2094 : }
2095 112648533 : }
2096 :
2097 : /* Convert move insns with constant inputs to additions if they are cheaper.
2098 : Return true if any changes were made. */
2099 : static bool
2100 1070192 : reload_cse_move2add (rtx_insn *first)
2101 : {
2102 1070192 : int i;
2103 1070192 : rtx_insn *insn;
2104 1070192 : bool changed = false;
2105 :
2106 101668240 : for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2107 : {
2108 100598048 : reg_set_luid[i] = 0;
2109 100598048 : reg_offset[i] = 0;
2110 100598048 : reg_base_reg[i] = 0;
2111 100598048 : reg_symbol_ref[i] = NULL_RTX;
2112 100598048 : reg_mode[i] = VOIDmode;
2113 : }
2114 :
2115 1070192 : move2add_last_label_luid = 0;
2116 1070192 : move2add_luid = 2;
2117 144624910 : for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
2118 : {
2119 143554718 : rtx set;
2120 :
2121 143554718 : if (LABEL_P (insn))
2122 : {
2123 5306722 : move2add_last_label_luid = move2add_luid;
2124 : /* We're going to increment move2add_luid twice after a
2125 : label, so that we can use move2add_last_label_luid + 1 as
2126 : the luid for constants. */
2127 5306722 : move2add_luid++;
2128 143554718 : continue;
2129 : }
2130 138247996 : if (! INSN_P (insn))
2131 23489057 : continue;
2132 114758939 : set = single_set (insn);
2133 : /* For simplicity, we only perform this optimization on
2134 : single-sets. */
2135 114758939 : scalar_int_mode mode;
2136 114758939 : if (set
2137 55901999 : && REG_P (SET_DEST (set))
2138 152971478 : && is_a <scalar_int_mode> (GET_MODE (SET_DEST (set)), &mode))
2139 : {
2140 28422445 : rtx reg = SET_DEST (set);
2141 28422445 : int regno = REGNO (reg);
2142 28422445 : rtx src = SET_SRC (set);
2143 :
2144 : /* Check if we have valid information on the contents of this
2145 : register in the mode of REG. */
2146 28422445 : if (move2add_valid_value_p (regno, mode)
2147 28422445 : && dbg_cnt (cse2_move2add))
2148 : {
2149 : /* Try to transform (set (REGX) (CONST_INT A))
2150 : ...
2151 : (set (REGX) (CONST_INT B))
2152 : to
2153 : (set (REGX) (CONST_INT A))
2154 : ...
2155 : (set (REGX) (plus (REGX) (CONST_INT B-A)))
2156 : or
2157 : (set (REGX) (CONST_INT A))
2158 : ...
2159 : (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
2160 : */
2161 :
2162 3972212 : if (CONST_INT_P (src)
2163 337674 : && reg_base_reg[regno] < 0
2164 150998 : && reg_symbol_ref[regno] == NULL_RTX)
2165 : {
2166 147555 : changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
2167 : src, insn);
2168 147555 : continue;
2169 : }
2170 :
2171 : /* Try to transform (set (REGX) (REGY))
2172 : (set (REGX) (PLUS (REGX) (CONST_INT A)))
2173 : ...
2174 : (set (REGX) (REGY))
2175 : (set (REGX) (PLUS (REGX) (CONST_INT B)))
2176 : to
2177 : (set (REGX) (REGY))
2178 : (set (REGX) (PLUS (REGX) (CONST_INT A)))
2179 : ...
2180 : (set (REGX) (plus (REGX) (CONST_INT B-A))) */
2181 3824657 : else if (REG_P (src)
2182 485565 : && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
2183 124506 : && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
2184 3949163 : && move2add_valid_value_p (REGNO (src), mode))
2185 : {
2186 93046 : rtx_insn *next = next_nonnote_nondebug_insn (insn);
2187 93046 : rtx set = NULL_RTX;
2188 93046 : if (next)
2189 93034 : set = single_set (next);
2190 93034 : if (set
2191 71649 : && SET_DEST (set) == reg
2192 7321 : && GET_CODE (SET_SRC (set)) == PLUS
2193 684 : && XEXP (SET_SRC (set), 0) == reg
2194 676 : && CONST_INT_P (XEXP (SET_SRC (set), 1)))
2195 : {
2196 421 : rtx src3 = XEXP (SET_SRC (set), 1);
2197 421 : unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
2198 421 : HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
2199 421 : HOST_WIDE_INT regno_offset = reg_offset[regno];
2200 421 : rtx new_src =
2201 842 : gen_int_mode (added_offset
2202 421 : + base_offset
2203 421 : - regno_offset,
2204 : mode);
2205 421 : bool success = false;
2206 421 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
2207 :
2208 421 : if (new_src == const0_rtx)
2209 : /* See above why we create (set (reg) (reg)) here. */
2210 43 : success
2211 43 : = validate_change (next, &SET_SRC (set), reg, 0);
2212 : else
2213 : {
2214 378 : rtx old_src = SET_SRC (set);
2215 378 : struct full_rtx_costs oldcst, newcst;
2216 378 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
2217 :
2218 378 : get_full_set_rtx_cost (set, &oldcst);
2219 378 : SET_SRC (set) = tem;
2220 378 : get_full_set_src_cost (tem, mode, &newcst);
2221 378 : SET_SRC (set) = old_src;
2222 378 : costs_add_n_insns (&oldcst, 1);
2223 :
2224 378 : rtx *setloc = GET_CODE (PATTERN (next)) == PARALLEL
2225 378 : ? &XVECEXP (PATTERN (next), 0, 0) : &PATTERN (next);
2226 378 : if (*setloc == set
2227 378 : && costs_lt_p (&newcst, &oldcst, speed)
2228 756 : && have_add2_insn (reg, new_src))
2229 : {
2230 378 : rtx newpat = gen_rtx_SET (reg, tem);
2231 378 : success
2232 378 : = validate_change (next, setloc, newpat, 0);
2233 : }
2234 : }
2235 421 : if (success)
2236 421 : delete_insn (insn);
2237 421 : changed |= success;
2238 421 : insn = next;
2239 : /* Make sure to perform any invalidations related to
2240 : NEXT/INSN since we're going to bypass the normal
2241 : flow with the continue below.
2242 :
2243 : Do this before recording the new mode/offset. */
2244 421 : reload_cse_move2add_invalidate (insn);
2245 421 : move2add_record_mode (reg);
2246 421 : reg_offset[regno]
2247 421 : = trunc_int_for_mode (added_offset + base_offset,
2248 : mode);
2249 421 : continue;
2250 421 : }
2251 : }
2252 : }
2253 :
2254 : /* Try to transform
2255 : (set (REGX) (CONST (PLUS (SYMBOL_REF) (CONST_INT A))))
2256 : ...
2257 : (set (REGY) (CONST (PLUS (SYMBOL_REF) (CONST_INT B))))
2258 : to
2259 : (set (REGX) (CONST (PLUS (SYMBOL_REF) (CONST_INT A))))
2260 : ...
2261 : (set (REGY) (CONST (PLUS (REGX) (CONST_INT B-A)))) */
2262 28274469 : if ((GET_CODE (src) == SYMBOL_REF
2263 26375169 : || (GET_CODE (src) == CONST
2264 63801 : && GET_CODE (XEXP (src, 0)) == PLUS
2265 63573 : && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF
2266 63551 : && CONST_INT_P (XEXP (XEXP (src, 0), 1))))
2267 28338020 : && dbg_cnt (cse2_move2add))
2268 : {
2269 1962851 : rtx sym, off;
2270 :
2271 1962851 : if (GET_CODE (src) == SYMBOL_REF)
2272 : {
2273 1899300 : sym = src;
2274 1899300 : off = const0_rtx;
2275 : }
2276 : else
2277 : {
2278 63551 : sym = XEXP (XEXP (src, 0), 0);
2279 63551 : off = XEXP (XEXP (src, 0), 1);
2280 : }
2281 :
2282 : /* If the reg already contains the value which is sum of
2283 : sym and some constant value, we can use an add2 insn. */
2284 1962851 : if (move2add_valid_value_p (regno, mode)
2285 200747 : && reg_base_reg[regno] < 0
2286 129604 : && reg_symbol_ref[regno] != NULL_RTX
2287 2016864 : && rtx_equal_p (sym, reg_symbol_ref[regno]))
2288 2244 : changed |= move2add_use_add2_insn (mode, reg, sym, off, insn);
2289 :
2290 : /* Otherwise, we have to find a register whose value is sum
2291 : of sym and some constant value. */
2292 : else
2293 1960607 : changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2294 :
2295 1962851 : continue;
2296 1962851 : }
2297 : }
2298 112648112 : reload_cse_move2add_invalidate (insn);
2299 : }
2300 1070192 : return changed;
2301 : }
2302 :
2303 : /* SET is a SET or CLOBBER that sets DST. DATA is the insn which
2304 : contains SET.
2305 : Update reg_set_luid, reg_offset and reg_base_reg accordingly.
2306 : Called from reload_cse_move2add via note_stores. */
2307 :
2308 : static void
2309 62959871 : move2add_note_store (rtx dst, const_rtx set, void *data)
2310 : {
2311 62959871 : rtx_insn *insn = (rtx_insn *) data;
2312 62959871 : unsigned int regno = 0;
2313 62959871 : scalar_int_mode mode;
2314 :
2315 62959871 : if (GET_CODE (dst) == SUBREG)
2316 2688 : regno = subreg_regno (dst);
2317 62957183 : else if (REG_P (dst))
2318 45162670 : regno = REGNO (dst);
2319 : else
2320 : return;
2321 :
2322 45165358 : if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2323 17211788 : goto invalidate;
2324 :
2325 27953570 : if (GET_CODE (set) == SET)
2326 : {
2327 27818264 : rtx note, sym = NULL_RTX;
2328 27818264 : rtx off;
2329 :
2330 27818264 : note = find_reg_equal_equiv_note (insn);
2331 27818264 : if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2332 : {
2333 89450 : sym = XEXP (note, 0);
2334 89450 : off = const0_rtx;
2335 : }
2336 4347261 : else if (note && GET_CODE (XEXP (note, 0)) == CONST
2337 10601 : && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2338 10388 : && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2339 10366 : && CONST_INT_P (XEXP (XEXP (XEXP (note, 0), 0), 1)))
2340 : {
2341 : sym = XEXP (XEXP (XEXP (note, 0), 0), 0);
2342 : off = XEXP (XEXP (XEXP (note, 0), 0), 1);
2343 : }
2344 :
2345 99816 : if (sym != NULL_RTX)
2346 : {
2347 99816 : move2add_record_sym_value (dst, sym, off);
2348 99816 : return;
2349 : }
2350 : }
2351 :
2352 27853754 : if (GET_CODE (set) == SET
2353 27718448 : && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2354 27717355 : && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2355 : {
2356 27714110 : rtx src = SET_SRC (set);
2357 27714110 : rtx base_reg;
2358 27714110 : unsigned HOST_WIDE_INT offset;
2359 27714110 : int base_regno;
2360 :
2361 27714110 : switch (GET_CODE (src))
2362 : {
2363 6236050 : case PLUS:
2364 6236050 : if (REG_P (XEXP (src, 0)))
2365 : {
2366 5938821 : base_reg = XEXP (src, 0);
2367 :
2368 5938821 : if (CONST_INT_P (XEXP (src, 1)))
2369 5107696 : offset = UINTVAL (XEXP (src, 1));
2370 831125 : else if (REG_P (XEXP (src, 1))
2371 831125 : && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2372 : {
2373 91068 : if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2374 91068 : && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2375 9477 : offset = reg_offset[REGNO (XEXP (src, 1))];
2376 : /* Maybe the first register is known to be a
2377 : constant. */
2378 81591 : else if (move2add_valid_value_p (REGNO (base_reg), mode)
2379 23523 : && reg_base_reg[REGNO (base_reg)] < 0
2380 82556 : && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2381 : {
2382 831 : offset = reg_offset[REGNO (base_reg)];
2383 831 : base_reg = XEXP (src, 1);
2384 : }
2385 : else
2386 80760 : goto invalidate;
2387 : }
2388 : else
2389 740057 : goto invalidate;
2390 :
2391 : break;
2392 : }
2393 :
2394 297229 : goto invalidate;
2395 :
2396 : case REG:
2397 : base_reg = src;
2398 : offset = 0;
2399 : break;
2400 :
2401 4495208 : case CONST_INT:
2402 : /* Start tracking the register as a constant. */
2403 4495208 : reg_base_reg[regno] = -1;
2404 4495208 : reg_symbol_ref[regno] = NULL_RTX;
2405 4495208 : reg_offset[regno] = INTVAL (SET_SRC (set));
2406 : /* We assign the same luid to all registers set to constants. */
2407 4495208 : reg_set_luid[regno] = move2add_last_label_luid + 1;
2408 4495208 : move2add_record_mode (dst);
2409 4495208 : return;
2410 :
2411 12079637 : default:
2412 12079637 : goto invalidate;
2413 : }
2414 :
2415 10021219 : base_regno = REGNO (base_reg);
2416 : /* If information about the base register is not valid, set it
2417 : up as a new base register, pretending its value is known
2418 : starting from the current insn. */
2419 10021219 : if (!move2add_valid_value_p (base_regno, mode))
2420 : {
2421 7355333 : reg_base_reg[base_regno] = base_regno;
2422 7355333 : reg_symbol_ref[base_regno] = NULL_RTX;
2423 7355333 : reg_offset[base_regno] = 0;
2424 7355333 : reg_set_luid[base_regno] = move2add_luid;
2425 7355333 : gcc_assert (GET_MODE (base_reg) == mode);
2426 7355333 : move2add_record_mode (base_reg);
2427 : }
2428 :
2429 : /* Copy base information from our base register. */
2430 10021219 : reg_set_luid[regno] = reg_set_luid[base_regno];
2431 10021219 : reg_base_reg[regno] = reg_base_reg[base_regno];
2432 10021219 : reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2433 :
2434 : /* Compute the sum of the offsets or constants. */
2435 10021219 : reg_offset[regno]
2436 10021219 : = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2437 :
2438 10021219 : move2add_record_mode (dst);
2439 10021219 : }
2440 : else
2441 : {
2442 139644 : invalidate:
2443 : /* Invalidate the contents of the register. */
2444 30549115 : move2add_record_mode (dst);
2445 30549115 : reg_mode[regno] = VOIDmode;
2446 : }
2447 : }
2448 :
2449 : namespace {
2450 :
2451 : const pass_data pass_data_postreload_cse =
2452 : {
2453 : RTL_PASS, /* type */
2454 : "postreload", /* name */
2455 : OPTGROUP_NONE, /* optinfo_flags */
2456 : TV_RELOAD_CSE_REGS, /* tv_id */
2457 : 0, /* properties_required */
2458 : 0, /* properties_provided */
2459 : 0, /* properties_destroyed */
2460 : 0, /* todo_flags_start */
2461 : TODO_df_finish, /* todo_flags_finish */
2462 : };
2463 :
2464 : class pass_postreload_cse : public rtl_opt_pass
2465 : {
2466 : public:
2467 294536 : pass_postreload_cse (gcc::context *ctxt)
2468 589072 : : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2469 : {}
2470 :
2471 : /* opt_pass methods: */
2472 1515929 : bool gate (function *) final override
2473 : {
2474 1515929 : return (optimize > 0 && reload_completed);
2475 : }
2476 :
2477 : unsigned int execute (function *) final override;
2478 :
2479 : }; // class pass_postreload_cse
2480 :
2481 : unsigned int
2482 1070192 : pass_postreload_cse::execute (function *fun)
2483 : {
2484 1070192 : if (!dbg_cnt (postreload_cse))
2485 : return 0;
2486 :
2487 : /* Do a very simple CSE pass over just the hard registers. */
2488 1070192 : reload_cse_regs (get_insns ());
2489 : /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2490 : Remove any EH edges associated with them. */
2491 1070192 : if (fun->can_throw_non_call_exceptions
2492 1070192 : && purge_all_dead_edges ())
2493 115 : cleanup_cfg (0);
2494 :
2495 : return 0;
2496 : }
2497 :
2498 : } // anon namespace
2499 :
2500 : rtl_opt_pass *
2501 294536 : make_pass_postreload_cse (gcc::context *ctxt)
2502 : {
2503 294536 : return new pass_postreload_cse (ctxt);
2504 : }
|