Branch data Line data Source code
1 : : /* Perform simple optimizations to clean up the result of reload.
2 : : Copyright (C) 1987-2025 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 : 1008570 : reload_cse_regs (rtx_insn *first ATTRIBUTE_UNUSED)
64 : : {
65 : 1008570 : bool moves_converted;
66 : 1008570 : reload_cse_regs_1 ();
67 : 1008570 : reload_combine ();
68 : 1008570 : moves_converted = reload_cse_move2add (first);
69 : 1008570 : if (flag_expensive_optimizations)
70 : : {
71 : 933022 : if (moves_converted)
72 : 8428 : reload_combine ();
73 : 933022 : reload_cse_regs_1 ();
74 : : }
75 : 1008570 : }
76 : :
77 : : /* Try to simplify INSN. Return true if the CFG may have changed. */
78 : : static bool
79 : 191449384 : reload_cse_simplify (rtx_insn *insn, rtx testreg)
80 : : {
81 : 191449384 : rtx body = PATTERN (insn);
82 : 191449384 : basic_block insn_bb = BLOCK_FOR_INSN (insn);
83 : 191449384 : 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 : 191449384 : if (NO_FUNCTION_CSE && CALL_P (insn))
88 : : return false;
89 : :
90 : : /* Remember if this insn has been sp += const_int. */
91 : 182762251 : rtx sp_set = set_for_reg_notes (insn);
92 : 182762251 : rtx sp_addend = NULL_RTX;
93 : 182762251 : if (sp_set
94 : 65215999 : && SET_DEST (sp_set) == stack_pointer_rtx
95 : 3287038 : && GET_CODE (SET_SRC (sp_set)) == PLUS
96 : 3259510 : && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
97 : 3259446 : && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
98 : 182762251 : sp_addend = XEXP (SET_SRC (sp_set), 1);
99 : :
100 : 182762251 : if (GET_CODE (body) == SET)
101 : : {
102 : 83596305 : 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 : 83596305 : count += reload_cse_simplify_set (body, insn);
110 : :
111 : 83596305 : if (!count && cselib_redundant_set_p (body))
112 : : {
113 : 228224 : if (check_for_inc_dec (insn))
114 : 228224 : delete_insn_and_edges (insn);
115 : : /* We're done with this insn. */
116 : 228224 : goto done;
117 : : }
118 : :
119 : 83368081 : if (count > 0)
120 : 146875 : apply_change_group ();
121 : : else
122 : 83221206 : reload_cse_simplify_operands (insn, testreg);
123 : : }
124 : 99165946 : else if (GET_CODE (body) == PARALLEL)
125 : : {
126 : 13474675 : int i;
127 : 13474675 : int count = 0;
128 : 13474675 : 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 : 13474675 : if (asm_noperands (body) >= 0)
134 : : {
135 : 586327 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
136 : : {
137 : 447557 : rtx part = XVECEXP (body, 0, i);
138 : 447557 : if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
139 : 193469 : 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 : 27012781 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
146 : : {
147 : 27008687 : rtx part = XVECEXP (body, 0, i);
148 : 27008687 : if (GET_CODE (part) == SET)
149 : : {
150 : 13376896 : if (! cselib_redundant_set_p (part))
151 : : break;
152 : 4214 : if (REG_P (SET_DEST (part))
153 : 4214 : && REG_FUNCTION_VALUE_P (SET_DEST (part)))
154 : : {
155 : 0 : if (value)
156 : : break;
157 : : value = SET_DEST (part);
158 : : }
159 : : }
160 : 13631791 : else if (GET_CODE (part) != CLOBBER && GET_CODE (part) != USE)
161 : : break;
162 : : }
163 : :
164 : 13474675 : if (i < 0)
165 : : {
166 : 4094 : if (check_for_inc_dec (insn))
167 : 4094 : delete_insn_and_edges (insn);
168 : : /* We're done with this insn. */
169 : 4094 : goto done;
170 : : }
171 : :
172 : : /* It's not a no-op, but we can try to simplify it. */
173 : 41246814 : for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
174 : 27776233 : if (GET_CODE (XVECEXP (body, 0, i)) == SET)
175 : 14148366 : count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
176 : :
177 : 13470581 : if (count > 0)
178 : 5002 : apply_change_group ();
179 : : else
180 : 13465579 : 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 : 182529933 : if (sp_addend
186 : 3259446 : && SET_DEST (sp_set) == stack_pointer_rtx
187 : 3259446 : && REG_P (SET_SRC (sp_set)))
188 : 3148 : set_dst_reg_note (insn, REG_EQUAL,
189 : 3148 : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
190 : : sp_addend), stack_pointer_rtx);
191 : :
192 : 182526785 : done:
193 : 365522331 : 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 : 1941592 : reload_cse_regs_1 (void)
215 : : {
216 : 1941592 : bool cfg_changed = false;
217 : 1941592 : basic_block bb;
218 : 1941592 : rtx_insn *insn;
219 : 1941592 : rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
220 : :
221 : 1941592 : cselib_init (CSELIB_RECORD_MEMORY);
222 : 1941592 : init_alias_analysis ();
223 : :
224 : 22070469 : 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 : 20128877 : rtx_insn *implicit_set;
230 : :
231 : 20128877 : implicit_set = NULL;
232 : 20128877 : if (EDGE_COUNT (bb->preds) <= 3)
233 : : {
234 : 19633840 : edge e;
235 : 19633840 : edge_iterator ei;
236 : 19633840 : rtx src = NULL_RTX;
237 : 19633840 : rtx dest = NULL_RTX;
238 : :
239 : : /* Iterate over each incoming edge and see if they
240 : : all have the same implicit set. */
241 : 19633970 : FOR_EACH_EDGE (e, ei, bb->preds)
242 : : {
243 : : /* Skip the entry/exit block. */
244 : 19633840 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
245 : : break;
246 : :
247 : : /* Verify this block ends with a suitable condjump */
248 : 17692305 : rtx_insn *condjump = BB_END (e->src);
249 : 17692305 : 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 : 13638073 : rtx pat = pc_set (condjump);
256 : 13638073 : rtx i_t_e = SET_SRC (pat);
257 : 13638073 : gcc_assert (GET_CODE (i_t_e) == IF_THEN_ELSE);
258 : 13638073 : rtx cond = XEXP (i_t_e, 0);
259 : :
260 : 13638073 : if ((((e->flags & EDGE_FALLTHRU) != 0)
261 : 13638073 : == (XEXP (i_t_e, 1) == pc_rtx))
262 : 13638073 : ? GET_CODE (cond) == EQ
263 : 8394947 : : GET_CODE (cond) == NE)
264 : : {
265 : : /* If this is the first time through record
266 : : the source and destination. */
267 : 5336199 : if (!dest)
268 : : {
269 : 5336199 : dest = XEXP (cond, 0);
270 : 5336199 : 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 : 5336199 : if (!REG_P (dest)
286 : 5336175 : || !(REG_P (src) || CONST_INT_P (src))
287 : 5336175 : || GET_MODE_CLASS (GET_MODE (dest)) != MODE_INT
288 : 130 : || reg_set_p (dest, condjump)
289 : 5336329 : || 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 : 19633840 : if (dest && ei_end_p (ei))
303 : 130 : implicit_set = make_insn_raw (gen_rtx_SET (dest, src));
304 : : }
305 : :
306 : 253554087 : FOR_BB_INSNS (bb, insn)
307 : : {
308 : 233425210 : 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 : 191449384 : if (implicit_set)
316 : : {
317 : 130 : cselib_process_insn (implicit_set);
318 : 130 : implicit_set = NULL;
319 : : }
320 : 191449384 : cfg_changed |= reload_cse_simplify (insn, testreg);
321 : : }
322 : :
323 : 233425210 : cselib_process_insn (insn);
324 : : }
325 : : }
326 : :
327 : : /* Clean up. */
328 : 1941592 : end_alias_analysis ();
329 : 1941592 : cselib_finish ();
330 : 1941592 : if (cfg_changed)
331 : 85 : cleanup_cfg (0);
332 : 1941592 : }
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 : 97744671 : reload_cse_simplify_set (rtx set, rtx_insn *insn)
342 : : {
343 : 97744671 : int did_change = 0;
344 : 97744671 : int dreg;
345 : 97744671 : rtx src;
346 : 97744671 : reg_class_t dclass;
347 : 97744671 : int old_cost;
348 : 97744671 : cselib_val *val;
349 : 97744671 : struct elt_loc_list *l;
350 : 97744671 : enum rtx_code extend_op = UNKNOWN;
351 : 97744671 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
352 : :
353 : 97744671 : dreg = true_regnum (SET_DEST (set));
354 : 97744671 : if (dreg < 0)
355 : : return 0;
356 : :
357 : 66400825 : src = SET_SRC (set);
358 : 66400825 : if (side_effects_p (src) || true_regnum (src) >= 0)
359 : 10620069 : return 0;
360 : :
361 : 55780756 : 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 : 55780756 : 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 : 55780756 : val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode);
373 : 55780756 : if (! val)
374 : : return 0;
375 : :
376 : : /* If memory loads are cheaper than register copies, don't change them. */
377 : 5605661 : if (MEM_P (src))
378 : 629410 : old_cost = memory_move_cost (GET_MODE (src), dclass, true);
379 : 4976251 : 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 : 4976251 : old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed);
384 : :
385 : 11263021 : for (l = val->locs; l; l = l->next)
386 : : {
387 : 5657360 : rtx this_rtx = l->loc;
388 : 5657360 : int this_cost;
389 : :
390 : 5657360 : if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
391 : : {
392 : 1987577 : 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 : 1987577 : this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed);
418 : : }
419 : 3669783 : else if (REG_P (this_rtx))
420 : : {
421 : 821355 : 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 : 821355 : this_cost = register_move_cost (GET_MODE (this_rtx),
428 : 821355 : REGNO_REG_CLASS (REGNO (this_rtx)),
429 : : dclass);
430 : : }
431 : : else
432 : 2848428 : continue;
433 : :
434 : : /* If equal costs, prefer registers over anything else. That
435 : : tends to lead to smaller instructions on some machines. */
436 : 2808932 : if (this_cost < old_cost
437 : 2662241 : || (this_cost == old_cost
438 : 1997240 : && REG_P (this_rtx)
439 : 17451 : && !REG_P (SET_SRC (set))))
440 : : {
441 : 152028 : 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 : 152028 : validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1);
451 : 152028 : 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 : 96686785 : reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
471 : : {
472 : 96686785 : int i, j;
473 : :
474 : : /* For each operand, all registers that are equivalent to it. */
475 : 96686785 : HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
476 : :
477 : 96686785 : const char *constraints[MAX_RECOG_OPERANDS];
478 : :
479 : : /* Vector recording how bad an alternative is. */
480 : 96686785 : int *alternative_reject;
481 : : /* Vector recording how many registers can be introduced by choosing
482 : : this alternative. */
483 : 96686785 : 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 : 96686785 : int *op_alt_regno[MAX_RECOG_OPERANDS];
488 : : /* Array of alternatives, sorted in order of decreasing desirability. */
489 : 96686785 : int *alternative_order;
490 : :
491 : 96686785 : extract_constrain_insn (insn);
492 : :
493 : 96686785 : if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
494 : : return 0;
495 : :
496 : 83596695 : alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
497 : 83596695 : alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
498 : 83596695 : alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
499 : 83596695 : memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
500 : 83596695 : memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
501 : :
502 : : /* For each operand, find out which regs are equivalent. */
503 : 270448264 : 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 : 186851569 : 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 : 186851569 : if (LABEL_P (recog_data.operand[i])
516 : 186838486 : || (NOTE_P (recog_data.operand[i])
517 : 80 : && NOTE_KIND (recog_data.operand[i]) == NOTE_INSN_DELETED_LABEL)
518 : 186838406 : || (CONSTANT_P (recog_data.operand[i])
519 : 32124246 : && recog_data.operand_mode[i] == VOIDmode))
520 : 547279 : continue;
521 : :
522 : 186304290 : op = recog_data.operand[i];
523 : 186304290 : 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 : 186304290 : if (side_effects_p (op))
571 : 4484705 : continue;
572 : 181819585 : v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode);
573 : 181819585 : if (! v)
574 : 120086881 : continue;
575 : :
576 : 180789900 : for (l = v->locs; l; l = l->next)
577 : 119057196 : if (REG_P (l->loc))
578 : 64118399 : SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
579 : : }
580 : :
581 : 83596695 : alternative_mask preferred = get_preferred_alternatives (insn);
582 : 270448264 : for (i = 0; i < recog_data.n_operands; i++)
583 : : {
584 : 186851569 : machine_mode mode;
585 : 186851569 : int regno;
586 : 186851569 : const char *p;
587 : :
588 : 186851569 : op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
589 : 2745334797 : for (j = 0; j < recog_data.n_alternatives; j++)
590 : 2558483228 : op_alt_regno[i][j] = -1;
591 : :
592 : 186851569 : p = constraints[i] = recog_data.constraints[i];
593 : 186851569 : mode = recog_data.operand_mode[i];
594 : :
595 : : /* Add the reject values for each alternative given by the constraints
596 : : for this operand. */
597 : 186851569 : j = 0;
598 : 7417041863 : while (*p != '\0')
599 : : {
600 : 7230190294 : char c = *p++;
601 : 7230190294 : if (c == ',')
602 : 2363217132 : j++;
603 : 4866973162 : else if (c == '?')
604 : 585621992 : alternative_reject[j] += 3;
605 : 4281351170 : else if (c == '!')
606 : 18622804 : 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 : 186851569 : regno = true_regnum (recog_data.operand[i]);
612 : 186851569 : if (regno >= 0
613 : 74344594 : || constraints[i][0] == '='
614 : 56262397 : || constraints[i][0] == '+')
615 : 130704595 : continue;
616 : :
617 : 5221668582 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
618 : : {
619 : 5165521608 : enum reg_class rclass = NO_REGS;
620 : :
621 : 5165521608 : if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
622 : 5164769686 : continue;
623 : :
624 : 751922 : 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 : 751922 : j = 0;
630 : 751922 : p = constraints[i];
631 : 39360150 : for (;;)
632 : : {
633 : 39360150 : char c = *p;
634 : :
635 : 39360150 : switch (c)
636 : : {
637 : 196618 : case 'g':
638 : 196618 : rclass = reg_class_subunion[rclass][GENERAL_REGS];
639 : 196618 : break;
640 : :
641 : 24865503 : default:
642 : 24865503 : rclass
643 : 24865503 : = (reg_class_subunion
644 : 24865503 : [rclass]
645 : 24865503 : [reg_class_for_constraint (lookup_constraint (p))]);
646 : 24865503 : break;
647 : :
648 : 14298029 : 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 : 14298029 : if (op_alt_regno[i][j] == -1
654 : 14229209 : && TEST_BIT (preferred, j)
655 : 9786475 : && reg_fits_class_p (testreg, rclass, 0, mode)
656 : 16737769 : && (!CONST_INT_P (recog_data.operand[i])
657 : 2305083 : || (set_src_cost (recog_data.operand[i], mode,
658 : : optimize_bb_for_speed_p
659 : 2305083 : (BLOCK_FOR_INSN (insn)))
660 : 2305083 : > set_src_cost (testreg, mode,
661 : : optimize_bb_for_speed_p
662 : 2305083 : (BLOCK_FOR_INSN (insn))))))
663 : : {
664 : 134657 : alternative_nregs[j]++;
665 : 134657 : op_alt_regno[i][j] = regno;
666 : : }
667 : 14298029 : j++;
668 : 14298029 : rclass = NO_REGS;
669 : 14298029 : break;
670 : : }
671 : 39360150 : p += CONSTRAINT_LEN (c, p);
672 : :
673 : 39360150 : 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 : 83596695 : alternative_order[0] = 0;
682 : 83596695 : 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 : 1306899552 : for (i = j = 0; i < recog_data.n_alternatives; i++)
689 : 1223302857 : if (alternative_reject[i] <= alternative_reject[which_alternative])
690 : 709165114 : alternative_order[j++] = i;
691 : 83596695 : 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 : 709165114 : for (i = 0; i < recog_data.n_alternatives - 1; i++)
696 : : {
697 : 625568419 : int best = i;
698 : 625568419 : int best_reject = alternative_reject[alternative_order[i]];
699 : 625568419 : int best_nregs = alternative_nregs[alternative_order[i]];
700 : :
701 : 4351578692 : for (j = i + 1; j < recog_data.n_alternatives; j++)
702 : : {
703 : 3726010273 : int this_reject = alternative_reject[alternative_order[j]];
704 : 3726010273 : int this_nregs = alternative_nregs[alternative_order[j]];
705 : :
706 : 3726010273 : if (this_reject < best_reject
707 : 3719058634 : || (this_reject == best_reject && this_nregs > best_nregs))
708 : : {
709 : 7029155 : best = j;
710 : 7029155 : best_reject = this_reject;
711 : 7029155 : best_nregs = this_nregs;
712 : : }
713 : : }
714 : :
715 : 625568419 : 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 : 83596695 : j = alternative_order[0];
721 : :
722 : 270448264 : for (i = 0; i < recog_data.n_operands; i++)
723 : : {
724 : 186851569 : machine_mode mode = recog_data.operand_mode[i];
725 : 186851569 : if (op_alt_regno[i][j] == -1)
726 : 186800235 : continue;
727 : :
728 : 51334 : validate_change (insn, recog_data.operand_loc[i],
729 : : gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
730 : : }
731 : :
732 : 84889696 : for (i = recog_data.n_dups - 1; i >= 0; i--)
733 : : {
734 : 1293001 : int op = recog_data.dup_num[i];
735 : 1293001 : machine_mode mode = recog_data.operand_mode[op];
736 : :
737 : 1293001 : if (op_alt_regno[op][j] == -1)
738 : 1292724 : continue;
739 : :
740 : 277 : validate_change (insn, recog_data.dup_loc[i],
741 : : gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
742 : : }
743 : :
744 : 83596695 : 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 : 185952 : reload_combine_split_one_ruid (int *pruid, int split_ruid)
820 : : {
821 : 185952 : if (*pruid > split_ruid)
822 : 8193 : (*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 : 659 : reload_combine_split_ruids (int split_ruid)
831 : : {
832 : 659 : unsigned i;
833 : :
834 : 659 : reload_combine_split_one_ruid (&reload_combine_ruid, split_ruid);
835 : 659 : reload_combine_split_one_ruid (&last_label_ruid, split_ruid);
836 : 659 : reload_combine_split_one_ruid (&last_jump_ruid, split_ruid);
837 : :
838 : 61287 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
839 : : {
840 : 60628 : int j, idx = reg_state[i].use_index;
841 : 60628 : reload_combine_split_one_ruid (®_state[i].use_ruid, split_ruid);
842 : 60628 : reload_combine_split_one_ruid (®_state[i].store_ruid, split_ruid);
843 : 60628 : reload_combine_split_one_ruid (®_state[i].real_store_ruid,
844 : : split_ruid);
845 : 60628 : if (idx < 0)
846 : 24562 : continue;
847 : 38157 : for (j = idx; j < RELOAD_COMBINE_MAX_USES; j++)
848 : : {
849 : 3591 : reload_combine_split_one_ruid (®_state[i].reg_use[j].ruid,
850 : : split_ruid);
851 : : }
852 : : }
853 : 659 : }
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 : 5837 : reload_combine_purge_insn_uses (rtx_insn *insn)
861 : : {
862 : 5837 : unsigned i;
863 : :
864 : 542841 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
865 : : {
866 : 537004 : int j, k, idx = reg_state[i].use_index;
867 : 537004 : if (idx < 0)
868 : 121421 : continue;
869 : : j = k = RELOAD_COMBINE_MAX_USES;
870 : 471124 : while (j-- > idx)
871 : : {
872 : 55541 : if (reg_state[i].reg_use[j].insn != insn)
873 : : {
874 : 48992 : k--;
875 : 48992 : if (k != j)
876 : 3750 : reg_state[i].reg_use[k] = reg_state[i].reg_use[j];
877 : : }
878 : : }
879 : 415583 : reg_state[i].use_index = k;
880 : : }
881 : 5837 : }
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 : 659 : reload_combine_purge_reg_uses_after_ruid (unsigned regno, int ruid)
888 : : {
889 : 659 : int j, k, idx = reg_state[regno].use_index;
890 : 659 : if (idx < 0)
891 : : return;
892 : : j = k = RELOAD_COMBINE_MAX_USES;
893 : 2593 : while (j-- > idx)
894 : : {
895 : 1934 : if (reg_state[regno].reg_use[j].ruid >= ruid)
896 : : {
897 : 856 : k--;
898 : 856 : if (k != j)
899 : 644 : reg_state[regno].reg_use[k] = reg_state[regno].reg_use[j];
900 : : }
901 : : }
902 : 659 : 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 : 3540393 : reload_combine_closest_single_use (unsigned regno, int ruid_limit)
911 : : {
912 : 3540393 : int i, best_ruid = 0;
913 : 3540393 : int use_idx = reg_state[regno].use_index;
914 : 3540393 : struct reg_use *retval;
915 : :
916 : 3540393 : if (use_idx < 0)
917 : : return NULL;
918 : : retval = NULL;
919 : 3555323 : for (i = use_idx; i < RELOAD_COMBINE_MAX_USES; i++)
920 : : {
921 : 2068647 : struct reg_use *use = reg_state[regno].reg_use + i;
922 : 2068647 : int this_ruid = use->ruid;
923 : 2068647 : if (this_ruid >= ruid_limit)
924 : 774900 : continue;
925 : 1293747 : if (this_ruid > best_ruid)
926 : : {
927 : : best_ruid = this_ruid;
928 : : retval = use;
929 : : }
930 : 347365 : else if (this_ruid == best_ruid)
931 : 2068647 : retval = NULL;
932 : : }
933 : 1486676 : if (last_label_ruid >= best_ruid)
934 : 613180 : 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 : 826 : fixup_debug_insns (rtx reg, rtx replacement, rtx_insn *from, rtx_insn *to)
946 : : {
947 : 826 : rtx_insn *insn;
948 : 6973 : for (insn = from; insn != to; insn = NEXT_INSN (insn))
949 : : {
950 : 6147 : rtx t;
951 : :
952 : 6147 : if (!DEBUG_BIND_INSN_P (insn))
953 : 4721 : continue;
954 : :
955 : 1426 : t = INSN_VAR_LOCATION_LOC (insn);
956 : 1426 : t = simplify_replace_rtx (t, reg, replacement);
957 : 1426 : validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0);
958 : : }
959 : 826 : }
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 : 742243 : try_replace_in_use (struct reg_use *use, rtx reg, rtx src)
967 : : {
968 : 742243 : rtx_insn *use_insn = use->insn;
969 : 742243 : rtx mem = use->containing_mem;
970 : 742243 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
971 : :
972 : 742243 : if (mem != NULL_RTX)
973 : : {
974 : 17233 : addr_space_t as = MEM_ADDR_SPACE (mem);
975 : 17233 : rtx oldaddr = XEXP (mem, 0);
976 : 17233 : rtx newaddr = NULL_RTX;
977 : 17233 : int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed);
978 : 17233 : int new_cost;
979 : :
980 : 17233 : newaddr = simplify_replace_rtx (oldaddr, reg, src);
981 : 17233 : if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as))
982 : : {
983 : 5680 : XEXP (mem, 0) = newaddr;
984 : 5680 : new_cost = address_cost (newaddr, GET_MODE (mem), as, speed);
985 : 5680 : XEXP (mem, 0) = oldaddr;
986 : 5680 : if (new_cost <= old_cost
987 : 5680 : && validate_change (use_insn,
988 : : &XEXP (mem, 0), newaddr, 0))
989 : : return true;
990 : : }
991 : : }
992 : : else
993 : : {
994 : 725010 : rtx new_set = single_set (use_insn);
995 : 725010 : if (new_set
996 : 724089 : && REG_P (SET_DEST (new_set))
997 : 286263 : && GET_CODE (SET_SRC (new_set)) == PLUS
998 : 18200 : && REG_P (XEXP (SET_SRC (new_set), 0))
999 : 16668 : && CONSTANT_P (XEXP (SET_SRC (new_set), 1)))
1000 : : {
1001 : 1304 : rtx new_src;
1002 : 1304 : machine_mode mode = GET_MODE (SET_DEST (new_set));
1003 : 1304 : int old_cost = set_src_cost (SET_SRC (new_set), mode, speed);
1004 : :
1005 : 1304 : gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg));
1006 : 1304 : new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src);
1007 : :
1008 : 1304 : if (set_src_cost (new_src, mode, speed) <= old_cost
1009 : 1304 : && 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 : 58240510 : reload_combine_recognize_const_pattern (rtx_insn *insn)
1025 : : {
1026 : 58240510 : int from_ruid = reload_combine_ruid;
1027 : 58240510 : rtx set, pat, reg, src, addreg;
1028 : 58240510 : unsigned int regno;
1029 : 58240510 : struct reg_use *use;
1030 : 58240510 : bool must_move_add;
1031 : 58240510 : rtx_insn *add_moved_after_insn = NULL;
1032 : 58240510 : int add_moved_after_ruid = 0;
1033 : 58240510 : int clobbered_regno = -1;
1034 : :
1035 : 58240510 : set = single_set (insn);
1036 : 58240510 : if (set == NULL_RTX)
1037 : : return false;
1038 : :
1039 : 54236009 : reg = SET_DEST (set);
1040 : 54236009 : src = SET_SRC (set);
1041 : 54236009 : if (!REG_P (reg)
1042 : 37262792 : || REG_NREGS (reg) != 1
1043 : 36652847 : || GET_MODE (reg) != Pmode
1044 : 75412836 : || reg == stack_pointer_rtx)
1045 : : return false;
1046 : :
1047 : 19496546 : 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 : 19496546 : if (GET_CODE (src) != PLUS
1054 : 3724169 : || !REG_P (XEXP (src, 0))
1055 : 3485710 : || !CONSTANT_P (XEXP (src, 1)))
1056 : : return false;
1057 : :
1058 : 2893713 : addreg = XEXP (src, 0);
1059 : 2893713 : must_move_add = rtx_equal_p (reg, addreg);
1060 : :
1061 : 2893713 : pat = PATTERN (insn);
1062 : 2893713 : 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 : 772256 : gcc_assert (GET_CODE (PATTERN (insn)) == PARALLEL);
1069 : 772256 : if (XVECLEN (pat, 0) != 2 || XVECEXP (pat, 0, 0) != set
1070 : 772256 : || GET_CODE (XVECEXP (pat, 0, 1)) != CLOBBER
1071 : 772256 : || !REG_P (XEXP (XVECEXP (pat, 0, 1), 0)))
1072 : : return false;
1073 : 772256 : clobbered_regno = REGNO (XEXP (XVECEXP (pat, 0, 1), 0));
1074 : : }
1075 : :
1076 : 3540393 : do
1077 : : {
1078 : 3540393 : use = reload_combine_closest_single_use (regno, from_ruid);
1079 : :
1080 : 3540393 : if (use)
1081 : : /* Start the search for the next use from here. */
1082 : 845849 : from_ruid = use->ruid;
1083 : :
1084 : 845849 : if (use && GET_MODE (*use->usep) == Pmode)
1085 : : {
1086 : 841158 : bool delete_add = false;
1087 : 841158 : rtx_insn *use_insn = use->insn;
1088 : 841158 : int use_ruid = use->ruid;
1089 : :
1090 : : /* Avoid moving the add insn past a jump. */
1091 : 841158 : 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 : 840878 : if (must_move_add && clobbered_regno >= 0
1097 : 111616 : && reg_state[clobbered_regno].real_store_ruid >= use_ruid)
1098 : : break;
1099 : :
1100 : 818615 : gcc_assert (reg_state[regno].store_ruid <= use_ruid);
1101 : : /* Avoid moving a use of ADDREG past a point where it is stored. */
1102 : 818615 : 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 : 742260 : if (must_move_add && reg_state[regno].store_ruid == use_ruid)
1108 : : {
1109 : 28810 : if (use->containing_mem == NULL_RTX)
1110 : : delete_add = true;
1111 : : else
1112 : : break;
1113 : : }
1114 : :
1115 : 742243 : if (try_replace_in_use (use, reg, src))
1116 : : {
1117 : 5837 : reload_combine_purge_insn_uses (use_insn);
1118 : 5837 : reload_combine_note_use (&PATTERN (use_insn), use_insn,
1119 : : use_ruid, NULL_RTX);
1120 : :
1121 : 5837 : if (delete_add)
1122 : : {
1123 : 55 : fixup_debug_insns (reg, src, insn, use_insn);
1124 : 55 : delete_insn (insn);
1125 : 55 : return true;
1126 : : }
1127 : 5782 : if (must_move_add)
1128 : : {
1129 : 1120 : add_moved_after_insn = use_insn;
1130 : 1120 : add_moved_after_ruid = use_ruid;
1131 : : }
1132 : 5782 : continue;
1133 : : }
1134 : : }
1135 : : /* If we get here, we couldn't handle this use. */
1136 : 3435641 : if (must_move_add)
1137 : : break;
1138 : : }
1139 : 2665825 : while (use);
1140 : :
1141 : 2893658 : if (!must_move_add || add_moved_after_insn == NULL_RTX)
1142 : : /* Process the add normally. */
1143 : : return false;
1144 : :
1145 : 659 : fixup_debug_insns (reg, src, insn, add_moved_after_insn);
1146 : :
1147 : 659 : reorder_insns (insn, insn, add_moved_after_insn);
1148 : 659 : reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
1149 : 659 : reload_combine_split_ruids (add_moved_after_ruid - 1);
1150 : 659 : reload_combine_note_use (&PATTERN (insn), insn,
1151 : : add_moved_after_ruid, NULL_RTX);
1152 : 659 : reg_state[regno].store_ruid = add_moved_after_ruid;
1153 : :
1154 : 659 : 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 : 58239796 : reload_combine_recognize_pattern (rtx_insn *insn)
1163 : : {
1164 : 58239796 : rtx set, reg, src;
1165 : :
1166 : 58239796 : set = single_set (insn);
1167 : 58239796 : if (set == NULL_RTX)
1168 : : return false;
1169 : :
1170 : 54235295 : reg = SET_DEST (set);
1171 : 54235295 : src = SET_SRC (set);
1172 : 54235295 : if (!REG_P (reg) || REG_NREGS (reg) != 1)
1173 : : return false;
1174 : :
1175 : 36652133 : unsigned int regno = REGNO (reg);
1176 : 36652133 : machine_mode mode = GET_MODE (reg);
1177 : :
1178 : 36652133 : if (reg_state[regno].use_index < 0
1179 : 36652133 : || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES)
1180 : : return false;
1181 : :
1182 : 23556700 : for (int i = reg_state[regno].use_index;
1183 : 43195278 : i < RELOAD_COMBINE_MAX_USES; i++)
1184 : : {
1185 : 24296074 : struct reg_use *use = reg_state[regno].reg_use + i;
1186 : 24296074 : if (GET_MODE (*use->usep) != mode)
1187 : : return false;
1188 : : /* Don't try to adjust (use (REGX)). */
1189 : 23560963 : if (GET_CODE (PATTERN (use->insn)) == USE
1190 : 23560963 : && &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 : 18899204 : if (GET_CODE (src) == PLUS
1209 : 2277314 : && reg_state[regno].all_offsets_match
1210 : 2035917 : && last_index_reg != -1
1211 : 2035917 : && REG_P (XEXP (src, 1))
1212 : 668156 : && rtx_equal_p (XEXP (src, 0), reg)
1213 : 484362 : && !rtx_equal_p (XEXP (src, 1), reg)
1214 : 19376887 : && last_label_ruid < reg_state[regno].use_ruid)
1215 : : {
1216 : 449085 : rtx base = XEXP (src, 1);
1217 : 449085 : rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
1218 : 449085 : rtx prev_set = prev ? single_set (prev) : NULL_RTX;
1219 : 449085 : rtx index_reg = NULL_RTX;
1220 : 449085 : rtx reg_sum = NULL_RTX;
1221 : 449085 : 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 : 449085 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
1229 : 449085 : || 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 : 8638434 : for (i = first_index_reg; i <= last_index_reg; i++)
1242 : : {
1243 : 8551584 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
1244 : 2987311 : && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
1245 : 1550221 : && reg_state[i].store_ruid <= reg_state[regno].use_ruid
1246 : 1535206 : && (crtl->abi->clobbers_full_reg_p (i)
1247 : 328463 : || df_regs_ever_live_p (i))
1248 : 1286870 : && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
1249 : 1285893 : && !fixed_regs[i] && !global_regs[i]
1250 : 526357 : && hard_regno_nregs (i, GET_MODE (reg)) == 1
1251 : 8685527 : && targetm.hard_regno_scratch_ok (i))
1252 : : {
1253 : 133943 : index_reg = gen_rtx_REG (GET_MODE (reg), i);
1254 : 133943 : reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
1255 : 133943 : 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 : 449085 : if (reg_sum
1264 : 449085 : && prev_set
1265 : 356653 : && CONST_INT_P (SET_SRC (prev_set))
1266 : 7087 : && rtx_equal_p (SET_DEST (prev_set), reg)
1267 : 449085 : && (reg_state[REGNO (base)].store_ruid
1268 : 2324 : <= reg_state[regno].use_ruid))
1269 : : {
1270 : : /* Change destination register and, if necessary, the constant
1271 : : value in PREV, the constant loading instruction. */
1272 : 2252 : validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
1273 : 2252 : 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 : 4550 : for (i = reg_state[regno].use_index;
1285 : 4550 : i < RELOAD_COMBINE_MAX_USES; i++)
1286 : 2298 : 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 : 2252 : if (apply_change_group ())
1293 : : {
1294 : 112 : 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 : 244 : for (i = reg_state[regno].use_index;
1299 : 244 : i < RELOAD_COMBINE_MAX_USES; i++)
1300 : : {
1301 : 132 : struct reg_use *use = reg_state[regno].reg_use + i;
1302 : 132 : reload_combine_note_use (&XEXP (*use->usep, 1), use->insn,
1303 : : use->ruid, use->containing_mem);
1304 : 132 : if (lowest_ruid == NULL || use->ruid < lowest_ruid->ruid)
1305 : 132 : lowest_ruid = use;
1306 : : }
1307 : :
1308 : 112 : fixup_debug_insns (reg, reg_sum, insn, lowest_ruid->insn);
1309 : :
1310 : : /* Delete the reg-reg addition. */
1311 : 112 : delete_insn (insn);
1312 : :
1313 : 112 : 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 : 112 : reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
1319 : 112 : return true;
1320 : : }
1321 : : }
1322 : : }
1323 : : return false;
1324 : : }
1325 : :
1326 : : static void
1327 : 1016998 : reload_combine (void)
1328 : : {
1329 : 1016998 : rtx_insn *insn, *prev;
1330 : 1016998 : basic_block bb;
1331 : 1016998 : unsigned int r;
1332 : 1016998 : int min_labelno, n_labels;
1333 : 1016998 : 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 : 1016998 : if (INDEX_REG_CLASS == NO_REGS)
1338 : : last_index_reg = -1;
1339 : 1016998 : else if (first_index_reg == -1 && last_index_reg == 0)
1340 : : {
1341 : 12955086 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1342 : 12815784 : if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
1343 : : {
1344 : 4318362 : if (first_index_reg == -1)
1345 : 139302 : first_index_reg = r;
1346 : :
1347 : 4318362 : 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 : 139302 : 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 : 1016998 : min_labelno = get_first_label_num ();
1364 : 1016998 : n_labels = max_label_num () - min_labelno;
1365 : 1016998 : label_live = XNEWVEC (HARD_REG_SET, n_labels);
1366 : 1016998 : CLEAR_HARD_REG_SET (ever_live_at_start);
1367 : :
1368 : 11926172 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
1369 : : {
1370 : 10909174 : insn = BB_HEAD (bb);
1371 : 10909174 : if (LABEL_P (insn))
1372 : : {
1373 : 5073215 : HARD_REG_SET live;
1374 : 5073215 : bitmap live_in = df_get_live_in (bb);
1375 : :
1376 : 10146430 : REG_SET_TO_HARD_REG_SET (live, live_in);
1377 : 5073215 : compute_use_by_pseudos (&live, live_in);
1378 : 5073215 : LABEL_LIVE (insn) = live;
1379 : 10146430 : ever_live_at_start |= live;
1380 : : }
1381 : : }
1382 : :
1383 : : /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
1384 : 1016998 : last_label_ruid = last_jump_ruid = reload_combine_ruid = 0;
1385 : 94580814 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1386 : : {
1387 : 93563816 : reg_state[r].store_ruid = 0;
1388 : 93563816 : reg_state[r].real_store_ruid = 0;
1389 : 93563816 : if (fixed_regs[r])
1390 : 46306551 : reg_state[r].use_index = -1;
1391 : : else
1392 : 47257265 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1393 : : }
1394 : :
1395 : 131440983 : for (insn = get_last_insn (); insn; insn = prev)
1396 : : {
1397 : 130423985 : bool control_flow_insn;
1398 : 130423985 : rtx note;
1399 : :
1400 : 130423985 : 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 : 130423985 : if (LABEL_P (insn))
1406 : 5080387 : last_label_ruid = reload_combine_ruid;
1407 : 125343598 : else if (BARRIER_P (insn))
1408 : : {
1409 : : /* Crossing a barrier resets all the use information. */
1410 : 277297356 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1411 : 274315664 : if (! fixed_regs[r])
1412 : 133267233 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1413 : : }
1414 : 122361906 : 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 : 42075711 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1419 : 41623284 : if (! fixed_regs[r]
1420 : 19588215 : && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
1421 : 664958 : reg_state[r].use_index = -1;
1422 : :
1423 : 130423985 : if (! NONDEBUG_INSN_P (insn))
1424 : 72183475 : continue;
1425 : :
1426 : 58240510 : reload_combine_ruid++;
1427 : :
1428 : 58240510 : control_flow_insn = control_flow_insn_p (insn);
1429 : 58240510 : if (control_flow_insn)
1430 : 8357386 : last_jump_ruid = reload_combine_ruid;
1431 : :
1432 : 58240510 : if (reload_combine_recognize_const_pattern (insn)
1433 : 58240510 : || reload_combine_recognize_pattern (insn))
1434 : 826 : continue;
1435 : :
1436 : 58239684 : note_stores (insn, reload_combine_note_store, NULL);
1437 : :
1438 : 58239684 : if (CALL_P (insn))
1439 : : {
1440 : 4696286 : rtx link;
1441 : 4696286 : HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
1442 : :
1443 : 436754598 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1444 : 432058312 : if (TEST_HARD_REG_BIT (used_regs, r))
1445 : : {
1446 : 383009621 : reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
1447 : 383009621 : reg_state[r].store_ruid = reload_combine_ruid;
1448 : : }
1449 : :
1450 : 13836291 : for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
1451 : 9140005 : link = XEXP (link, 1))
1452 : : {
1453 : 9140005 : rtx setuse = XEXP (link, 0);
1454 : 9140005 : rtx usage_rtx = XEXP (setuse, 0);
1455 : :
1456 : 9140005 : if (GET_CODE (setuse) == USE && REG_P (usage_rtx))
1457 : : {
1458 : 8610538 : unsigned int end_regno = END_REGNO (usage_rtx);
1459 : 17276086 : for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i)
1460 : 8665548 : reg_state[i].use_index = -1;
1461 : : }
1462 : : }
1463 : : }
1464 : :
1465 : 58239684 : 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 : 8357386 : HARD_REG_SET *live;
1470 : :
1471 : 9724171 : if ((condjump_p (insn) || condjump_in_parallel_p (insn))
1472 : 8357469 : && JUMP_LABEL (insn))
1473 : : {
1474 : 6990684 : if (ANY_RETURN_P (JUMP_LABEL (insn)))
1475 : : live = NULL;
1476 : : else
1477 : 6990684 : live = &LABEL_LIVE (JUMP_LABEL (insn));
1478 : : }
1479 : : else
1480 : : live = &ever_live_at_start;
1481 : :
1482 : 8357386 : if (live)
1483 : 777236898 : for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1484 : 768879512 : if (TEST_HARD_REG_BIT (*live, r))
1485 : 41323544 : reg_state[r].use_index = -1;
1486 : : }
1487 : :
1488 : 58239684 : reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
1489 : : NULL_RTX);
1490 : :
1491 : 81162486 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1492 : : {
1493 : 22922802 : 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 : 1016998 : 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 : 62751754 : reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
1512 : : {
1513 : 62751754 : int regno = 0;
1514 : 62751754 : int i;
1515 : 62751754 : machine_mode mode = GET_MODE (dst);
1516 : :
1517 : 62751754 : if (GET_CODE (dst) == SUBREG)
1518 : : {
1519 : 7090 : regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1520 : 3545 : GET_MODE (SUBREG_REG (dst)),
1521 : 3545 : SUBREG_BYTE (dst),
1522 : : GET_MODE (dst));
1523 : 3545 : dst = SUBREG_REG (dst);
1524 : : }
1525 : :
1526 : : /* Some targets do argument pushes without adding REG_INC notes. */
1527 : :
1528 : 62751754 : if (MEM_P (dst))
1529 : : {
1530 : 10094081 : dst = XEXP (dst, 0);
1531 : 10094081 : if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1532 : 10094081 : || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC
1533 : 8491580 : || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY)
1534 : : {
1535 : 1685091 : unsigned int end_regno = END_REGNO (XEXP (dst, 0));
1536 : 3370182 : 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 : 1685091 : reg_state[i].use_index = -1;
1542 : 1685091 : reg_state[i].store_ruid = reload_combine_ruid;
1543 : 1685091 : reg_state[i].real_store_ruid = reload_combine_ruid;
1544 : : }
1545 : : }
1546 : : else
1547 : : return;
1548 : : }
1549 : :
1550 : 54342764 : if (!REG_P (dst))
1551 : : return;
1552 : 45654183 : 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 : 45654183 : if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1558 : 45652753 : || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1559 : : {
1560 : 10488 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1561 : : {
1562 : 5244 : reg_state[i].use_index = -1;
1563 : 5244 : reg_state[i].store_ruid = reload_combine_ruid;
1564 : 5244 : reg_state[i].real_store_ruid = reload_combine_ruid;
1565 : : }
1566 : : }
1567 : : else
1568 : : {
1569 : 91915451 : for (i = end_hard_regno (mode, regno) - 1; i >= regno; i--)
1570 : : {
1571 : 46266512 : reg_state[i].store_ruid = reload_combine_ruid;
1572 : 46266512 : if (GET_CODE (set) == SET)
1573 : 38681273 : reg_state[i].real_store_ruid = reload_combine_ruid;
1574 : 46266512 : 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 : 205031611 : reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
1585 : : {
1586 : 243084188 : rtx x = *xp;
1587 : 243084188 : enum rtx_code code = x->code;
1588 : 243084188 : const char *fmt;
1589 : 243084188 : int i, j;
1590 : 243084188 : rtx offset = const0_rtx; /* For the REG case below. */
1591 : :
1592 : 243084188 : switch (code)
1593 : : {
1594 : 55119165 : case SET:
1595 : 55119165 : if (REG_P (SET_DEST (x)))
1596 : : {
1597 : 38052577 : reload_combine_note_use (&SET_SRC (x), insn, ruid, NULL_RTX);
1598 : 38052577 : return;
1599 : : }
1600 : : break;
1601 : :
1602 : 661259 : case USE:
1603 : : /* If this is the USE of a return value, we can't change it. */
1604 : 661259 : 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 : 548104 : rtx reg = XEXP (x, 0);
1608 : 548104 : unsigned int end_regno = END_REGNO (reg);
1609 : 1124357 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
1610 : 576253 : reg_state[regno].use_index = -1;
1611 : : return;
1612 : : }
1613 : : break;
1614 : :
1615 : 7212044 : case CLOBBER:
1616 : 7212044 : if (REG_P (SET_DEST (x)))
1617 : : {
1618 : : /* No spurious CLOBBERs of pseudo registers may remain. */
1619 : 7161652 : gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1620 : : return;
1621 : : }
1622 : : break;
1623 : :
1624 : 21780006 : case PLUS:
1625 : : /* We are interested in (plus (reg) (const_int)) . */
1626 : 21780006 : if (!REG_P (XEXP (x, 0))
1627 : 19671464 : || !CONST_INT_P (XEXP (x, 1)))
1628 : : break;
1629 : : offset = XEXP (x, 1);
1630 : : x = XEXP (x, 0);
1631 : : /* Fall through. */
1632 : 56478657 : case REG:
1633 : 56478657 : {
1634 : 56478657 : int regno = REGNO (x);
1635 : 56478657 : int use_index;
1636 : 56478657 : int nregs;
1637 : :
1638 : : /* No spurious USEs of pseudo registers may remain. */
1639 : 56478657 : gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1640 : :
1641 : 56478657 : nregs = REG_NREGS (x);
1642 : :
1643 : : /* We can't substitute into multi-hard-reg uses. */
1644 : 56478657 : if (nregs > 1)
1645 : : {
1646 : 1197519 : while (--nregs >= 0)
1647 : 798346 : 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 : 56079484 : 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 : 56077459 : use_index = --reg_state[regno].use_index;
1661 : 56077459 : if (use_index < 0)
1662 : : return;
1663 : :
1664 : 34169920 : 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 : 26032532 : reg_state[regno].offset = offset;
1669 : 26032532 : reg_state[regno].all_offsets_match = true;
1670 : 26032532 : reg_state[regno].use_ruid = ruid;
1671 : : }
1672 : : else
1673 : : {
1674 : 8137388 : if (reg_state[regno].use_ruid > ruid)
1675 : 753 : reg_state[regno].use_ruid = ruid;
1676 : :
1677 : 8137388 : if (! rtx_equal_p (offset, reg_state[regno].offset))
1678 : 3776062 : reg_state[regno].all_offsets_match = false;
1679 : : }
1680 : :
1681 : 34169920 : reg_state[regno].reg_use[use_index].insn = insn;
1682 : 34169920 : reg_state[regno].reg_use[use_index].ruid = ruid;
1683 : 34169920 : reg_state[regno].reg_use[use_index].containing_mem = containing_mem;
1684 : 34169920 : reg_state[regno].reg_use[use_index].usep = xp;
1685 : 34169920 : return;
1686 : : }
1687 : :
1688 : : case MEM:
1689 : 140843198 : containing_mem = x;
1690 : : break;
1691 : :
1692 : : default:
1693 : : break;
1694 : : }
1695 : :
1696 : : /* Recursively process the components of X. */
1697 : 140843198 : fmt = GET_RTX_FORMAT (code);
1698 : 359827325 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1699 : : {
1700 : 218984127 : if (fmt[i] == 'e')
1701 : 127535039 : reload_combine_note_use (&XEXP (x, i), insn, ruid, containing_mem);
1702 : 91449088 : else if (fmt[i] == 'E')
1703 : : {
1704 : 28695053 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1705 : 19250260 : 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 : 50980070 : move2add_record_mode (rtx reg)
1761 : : {
1762 : 50980070 : int regno, nregs;
1763 : 50980070 : machine_mode mode = GET_MODE (reg);
1764 : :
1765 : 50980070 : if (GET_CODE (reg) == SUBREG)
1766 : : {
1767 : 3519 : regno = subreg_regno (reg);
1768 : 3519 : nregs = subreg_nregs (reg);
1769 : : }
1770 : 50976551 : else if (REG_P (reg))
1771 : : {
1772 : 50976551 : regno = REGNO (reg);
1773 : 50976551 : nregs = REG_NREGS (reg);
1774 : : }
1775 : : else
1776 : 0 : gcc_unreachable ();
1777 : 51640935 : for (int i = nregs - 1; i > 0; i--)
1778 : 660865 : reg_mode[regno + i] = BLKmode;
1779 : 50980070 : reg_mode[regno] = mode;
1780 : 50980070 : }
1781 : :
1782 : : /* Record that REG is being set to the sum of SYM and OFF. */
1783 : :
1784 : : static void
1785 : 2061157 : move2add_record_sym_value (rtx reg, rtx sym, rtx off)
1786 : : {
1787 : 2061157 : int regno = REGNO (reg);
1788 : :
1789 : 2061157 : move2add_record_mode (reg);
1790 : 2061157 : reg_set_luid[regno] = move2add_luid;
1791 : 2061157 : reg_base_reg[regno] = -1;
1792 : 2061157 : reg_symbol_ref[regno] = sym;
1793 : 2061157 : reg_offset[regno] = INTVAL (off);
1794 : 2061157 : }
1795 : :
1796 : : /* Check if REGNO contains a valid value in MODE. */
1797 : :
1798 : : static bool
1799 : 207308924 : move2add_valid_value_p (int regno, scalar_int_mode mode)
1800 : : {
1801 : 207308924 : if (reg_set_luid[regno] <= move2add_last_label_luid)
1802 : : return false;
1803 : :
1804 : 20767901 : if (mode != reg_mode[regno])
1805 : : {
1806 : 11064919 : scalar_int_mode old_mode;
1807 : 11064919 : if (!is_a <scalar_int_mode> (reg_mode[regno], &old_mode)
1808 : 7095780 : || !MODES_OK_FOR_MOVE2ADD (mode, old_mode)
1809 : 514845 : || !REG_CAN_CHANGE_MODE_P (regno, old_mode, mode))
1810 : 10550074 : 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 : 514845 : poly_int64 s_off = subreg_lowpart_offset (mode, old_mode);
1816 : 514845 : s_off = subreg_regno_offset (regno, old_mode, s_off, mode);
1817 : 514845 : 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 : 10267576 : for (int i = end_hard_regno (mode, regno) - 1; i > regno; i--)
1826 : 54501 : 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 : 145184 : move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1840 : : rtx_insn *insn)
1841 : : {
1842 : 145184 : rtx set = single_set (insn);
1843 : 145184 : rtx src = SET_SRC (set);
1844 : 145184 : int regno = REGNO (reg);
1845 : 145184 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
1846 : 145184 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1847 : 145184 : 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 : 145184 : 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 : 18056 : if (INTVAL (off) == reg_offset [regno])
1862 : 16497 : changed = validate_change (insn, &SET_SRC (set), reg, 0);
1863 : : }
1864 : : else
1865 : : {
1866 : 127128 : struct full_rtx_costs oldcst, newcst;
1867 : 127128 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
1868 : :
1869 : 127128 : get_full_set_rtx_cost (set, &oldcst);
1870 : 127128 : SET_SRC (set) = tem;
1871 : 127128 : get_full_set_rtx_cost (set, &newcst);
1872 : 127128 : SET_SRC (set) = src;
1873 : :
1874 : 127128 : if (costs_lt_p (&newcst, &oldcst, speed)
1875 : 127128 : && have_add2_insn (reg, new_src))
1876 : 2734 : changed = validate_change (insn, &SET_SRC (set), tem, 0);
1877 : 124394 : else if (sym == NULL_RTX && mode != BImode)
1878 : : {
1879 : 122736 : scalar_int_mode narrow_mode;
1880 : 408990 : FOR_EACH_MODE_UNTIL (narrow_mode, mode)
1881 : : {
1882 : 286254 : if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1883 : 286254 : && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
1884 : 214289 : == (INTVAL (off) & ~GET_MODE_MASK (narrow_mode))))
1885 : : {
1886 : 101077 : rtx narrow_reg = gen_lowpart_common (narrow_mode, reg);
1887 : 101077 : rtx narrow_src = gen_int_mode (INTVAL (off),
1888 : : narrow_mode);
1889 : 101077 : rtx new_set
1890 : 101077 : = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode,
1891 : : narrow_reg),
1892 : : narrow_src);
1893 : 101077 : 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 : 101077 : rtx *setloc = GET_CODE (PATTERN (insn)) == PARALLEL
1899 : 101077 : ? &XVECEXP (PATTERN (insn), 0, 0) : &PATTERN (insn);
1900 : 101077 : 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 : 145184 : move2add_record_sym_value (reg, sym, off);
1911 : 145184 : 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 : 1837078 : move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
1926 : : rtx_insn *insn)
1927 : : {
1928 : 1837078 : rtx set = single_set (insn);
1929 : 1837078 : rtx src = SET_SRC (set);
1930 : 1837078 : int regno = REGNO (reg);
1931 : 1837078 : int min_regno = 0;
1932 : 1837078 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
1933 : 1837078 : int i;
1934 : 1837078 : bool changed = false;
1935 : 1837078 : struct full_rtx_costs oldcst, newcst, mincst;
1936 : 1837078 : rtx plus_expr;
1937 : :
1938 : 1837078 : init_costs_to_max (&mincst);
1939 : 1837078 : get_full_set_rtx_cost (set, &oldcst);
1940 : :
1941 : 1837078 : plus_expr = gen_rtx_PLUS (GET_MODE (reg), reg, const0_rtx);
1942 : 1837078 : SET_SRC (set) = plus_expr;
1943 : :
1944 : 170847595 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1945 : 169010527 : if (move2add_valid_value_p (i, mode)
1946 : 3540873 : && reg_base_reg[i] < 0
1947 : 1453661 : && reg_symbol_ref[i] != NULL_RTX
1948 : 169949739 : && rtx_equal_p (sym, reg_symbol_ref[i]))
1949 : : {
1950 : 39672 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[i],
1951 : 19836 : 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 : 19836 : if (new_src == const0_rtx)
1959 : : {
1960 : 10 : init_costs_to_zero (&mincst);
1961 : 10 : min_regno = i;
1962 : 10 : break;
1963 : : }
1964 : : else
1965 : : {
1966 : 19826 : XEXP (plus_expr, 1) = new_src;
1967 : 19826 : get_full_set_rtx_cost (set, &newcst);
1968 : :
1969 : 19826 : if (costs_lt_p (&newcst, &mincst, speed))
1970 : : {
1971 : 19262 : mincst = newcst;
1972 : 19262 : min_regno = i;
1973 : : }
1974 : : }
1975 : : }
1976 : 1837078 : SET_SRC (set) = src;
1977 : :
1978 : 1837078 : if (costs_lt_p (&mincst, &oldcst, speed))
1979 : : {
1980 : 35 : rtx tem;
1981 : :
1982 : 35 : tem = gen_rtx_REG (GET_MODE (reg), min_regno);
1983 : 35 : if (i != min_regno)
1984 : : {
1985 : 50 : rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[min_regno],
1986 : 25 : GET_MODE (reg));
1987 : 25 : tem = gen_rtx_PLUS (GET_MODE (reg), tem, new_src);
1988 : : }
1989 : 35 : if (validate_change (insn, &SET_SRC (set), tem, 0))
1990 : 1837078 : changed = true;
1991 : : }
1992 : 1837078 : reg_set_luid[regno] = move2add_luid;
1993 : 1837078 : move2add_record_sym_value (reg, sym, off);
1994 : 1837078 : return changed;
1995 : : }
1996 : :
1997 : : /* Perform any invalidations necessary for INSN. */
1998 : :
1999 : : static void
2000 : 95406280 : reload_cse_move2add_invalidate (rtx_insn *insn)
2001 : : {
2002 : 117070869 : for (rtx note = REG_NOTES (insn); note; note = XEXP (note, 1))
2003 : : {
2004 : 21664589 : 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 : 95406280 : subrtx_var_iterator::array_type array;
2019 : 493766008 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
2020 : : {
2021 : 398359728 : rtx mem = *iter;
2022 : 398359728 : if (mem
2023 : 398359728 : && MEM_P (mem)
2024 : 26250100 : && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
2025 : : {
2026 : 1647761 : if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
2027 : 1647761 : reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
2028 : : }
2029 : : }
2030 : :
2031 : 95406280 : 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 : 95406280 : if (any_condjump_p (insn))
2036 : : {
2037 : 4474773 : rtx cnd = fis_get_condition (insn);
2038 : :
2039 : 4474773 : if (cnd != NULL_RTX
2040 : 4014573 : && GET_CODE (cnd) == NE
2041 : 1812221 : && REG_P (XEXP (cnd, 0))
2042 : 1216685 : && !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 : 1216685 : && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
2048 : 1216684 : && REG_NREGS (XEXP (cnd, 0)) == 1
2049 : 5691457 : && CONST_INT_P (XEXP (cnd, 1)))
2050 : : {
2051 : 835477 : rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1));
2052 : 835477 : 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 : 95406280 : if (CALL_P (insn))
2059 : : {
2060 : 4489205 : function_abi callee_abi = insn_callee_abi (insn);
2061 : 417496065 : for (int i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2062 : 413006860 : if (reg_mode[i] != VOIDmode
2063 : 20748042 : && reg_mode[i] != BLKmode
2064 : 433174287 : && callee_abi.clobbers_reg_p (reg_mode[i], i))
2065 : : /* Reset the information about this register. */
2066 : 7743507 : reg_mode[i] = VOIDmode;
2067 : : }
2068 : 95406280 : }
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 : 1008570 : reload_cse_move2add (rtx_insn *first)
2074 : : {
2075 : 1008570 : int i;
2076 : 1008570 : rtx_insn *insn;
2077 : 1008570 : bool changed = false;
2078 : :
2079 : 93797010 : for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
2080 : : {
2081 : 92788440 : reg_set_luid[i] = 0;
2082 : 92788440 : reg_offset[i] = 0;
2083 : 92788440 : reg_base_reg[i] = 0;
2084 : 92788440 : reg_symbol_ref[i] = NULL_RTX;
2085 : 92788440 : reg_mode[i] = VOIDmode;
2086 : : }
2087 : :
2088 : 1008570 : move2add_last_label_luid = 0;
2089 : 1008570 : move2add_luid = 2;
2090 : 124844856 : for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
2091 : : {
2092 : 123836286 : rtx set;
2093 : :
2094 : 123836286 : if (LABEL_P (insn))
2095 : : {
2096 : 4823960 : 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 : 4823960 : move2add_luid++;
2101 : 128660246 : continue;
2102 : : }
2103 : 119012326 : if (! INSN_P (insn))
2104 : 21623784 : continue;
2105 : 97388542 : set = single_set (insn);
2106 : : /* For simplicity, we only perform this optimization on
2107 : : single-sets. */
2108 : 97388542 : scalar_int_mode mode;
2109 : 97388542 : if (set
2110 : 51476611 : && REG_P (SET_DEST (set))
2111 : 132763451 : && is_a <scalar_int_mode> (GET_MODE (SET_DEST (set)), &mode))
2112 : : {
2113 : 26369070 : rtx reg = SET_DEST (set);
2114 : 26369070 : int regno = REGNO (reg);
2115 : 26369070 : 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 : 26369070 : if (move2add_valid_value_p (regno, mode)
2120 : 26369070 : && 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 : 3751139 : if (CONST_INT_P (src)
2136 : 327604 : && reg_base_reg[regno] < 0
2137 : 145702 : && reg_symbol_ref[regno] == NULL_RTX)
2138 : : {
2139 : 143211 : changed |= move2add_use_add2_insn (mode, reg, NULL_RTX,
2140 : : src, insn);
2141 : 143211 : 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 : 3607928 : else if (REG_P (src)
2155 : 450558 : && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
2156 : 110590 : && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
2157 : 3718518 : && move2add_valid_value_p (REGNO (src), mode))
2158 : : {
2159 : 85746 : rtx_insn *next = next_nonnote_nondebug_insn (insn);
2160 : 85746 : rtx set = NULL_RTX;
2161 : 85746 : if (next)
2162 : 85732 : set = single_set (next);
2163 : 85732 : if (set
2164 : 66479 : && SET_DEST (set) == reg
2165 : 5294 : && GET_CODE (SET_SRC (set)) == PLUS
2166 : 670 : && XEXP (SET_SRC (set), 0) == reg
2167 : 666 : && CONST_INT_P (XEXP (SET_SRC (set), 1)))
2168 : : {
2169 : 435 : rtx src3 = XEXP (SET_SRC (set), 1);
2170 : 435 : unsigned HOST_WIDE_INT added_offset = UINTVAL (src3);
2171 : 435 : HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
2172 : 435 : HOST_WIDE_INT regno_offset = reg_offset[regno];
2173 : 435 : rtx new_src =
2174 : 870 : gen_int_mode (added_offset
2175 : 435 : + base_offset
2176 : 435 : - regno_offset,
2177 : : mode);
2178 : 435 : bool success = false;
2179 : 435 : bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
2180 : :
2181 : 435 : if (new_src == const0_rtx)
2182 : : /* See above why we create (set (reg) (reg)) here. */
2183 : 28 : success
2184 : 28 : = validate_change (next, &SET_SRC (set), reg, 0);
2185 : : else
2186 : : {
2187 : 407 : rtx old_src = SET_SRC (set);
2188 : 407 : struct full_rtx_costs oldcst, newcst;
2189 : 407 : rtx tem = gen_rtx_PLUS (mode, reg, new_src);
2190 : :
2191 : 407 : get_full_set_rtx_cost (set, &oldcst);
2192 : 407 : SET_SRC (set) = tem;
2193 : 407 : get_full_set_src_cost (tem, mode, &newcst);
2194 : 407 : SET_SRC (set) = old_src;
2195 : 407 : costs_add_n_insns (&oldcst, 1);
2196 : :
2197 : 407 : rtx *setloc = GET_CODE (PATTERN (next)) == PARALLEL
2198 : 407 : ? &XVECEXP (PATTERN (next), 0, 0) : &PATTERN (next);
2199 : 407 : if (*setloc == set
2200 : 407 : && costs_lt_p (&newcst, &oldcst, speed)
2201 : 814 : && have_add2_insn (reg, new_src))
2202 : : {
2203 : 407 : rtx newpat = gen_rtx_SET (reg, tem);
2204 : 407 : success
2205 : 407 : = validate_change (next, setloc, newpat, 0);
2206 : : }
2207 : : }
2208 : 435 : if (success)
2209 : 435 : delete_insn (insn);
2210 : 435 : changed |= success;
2211 : 435 : 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 : 435 : reload_cse_move2add_invalidate (insn);
2218 : 435 : move2add_record_mode (reg);
2219 : 435 : reg_offset[regno]
2220 : 435 : = trunc_int_for_mode (added_offset + base_offset,
2221 : : mode);
2222 : 435 : continue;
2223 : 435 : }
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 : 26225424 : if ((GET_CODE (src) == SYMBOL_REF
2236 : 24450949 : || (GET_CODE (src) == CONST
2237 : 64783 : && GET_CODE (XEXP (src, 0)) == PLUS
2238 : 64595 : && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF
2239 : 64576 : && CONST_INT_P (XEXP (XEXP (src, 0), 1))))
2240 : 26290000 : && dbg_cnt (cse2_move2add))
2241 : : {
2242 : 1839051 : rtx sym, off;
2243 : :
2244 : 1839051 : if (GET_CODE (src) == SYMBOL_REF)
2245 : : {
2246 : 1774475 : sym = src;
2247 : 1774475 : off = const0_rtx;
2248 : : }
2249 : : else
2250 : : {
2251 : 64576 : sym = XEXP (XEXP (src, 0), 0);
2252 : 64576 : 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 : 1839051 : if (move2add_valid_value_p (regno, mode)
2258 : 188197 : && reg_base_reg[regno] < 0
2259 : 125713 : && reg_symbol_ref[regno] != NULL_RTX
2260 : 1892927 : && rtx_equal_p (sym, reg_symbol_ref[regno]))
2261 : 1973 : 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 : 1837078 : changed |= move2add_use_add3_insn (mode, reg, sym, off, insn);
2267 : :
2268 : 1839051 : continue;
2269 : 1839051 : }
2270 : : }
2271 : 95405845 : reload_cse_move2add_invalidate (insn);
2272 : : }
2273 : 1008570 : 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 : 58478071 : move2add_note_store (rtx dst, const_rtx set, void *data)
2283 : : {
2284 : 58478071 : rtx_insn *insn = (rtx_insn *) data;
2285 : 58478071 : unsigned int regno = 0;
2286 : 58478071 : scalar_int_mode mode;
2287 : :
2288 : 58478071 : if (GET_CODE (dst) == SUBREG)
2289 : 3519 : regno = subreg_regno (dst);
2290 : 58474552 : else if (REG_P (dst))
2291 : 42257058 : regno = REGNO (dst);
2292 : : else
2293 : 58478071 : return;
2294 : :
2295 : 42260577 : if (!is_a <scalar_int_mode> (GET_MODE (dst), &mode))
2296 : 15903829 : goto invalidate;
2297 : :
2298 : 26356748 : if (GET_CODE (set) == SET)
2299 : : {
2300 : 25805796 : rtx note, sym = NULL_RTX;
2301 : 25805796 : rtx off;
2302 : :
2303 : 25805796 : note = find_reg_equal_equiv_note (insn);
2304 : 25805796 : if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF)
2305 : : {
2306 : 68756 : sym = XEXP (note, 0);
2307 : 68756 : off = const0_rtx;
2308 : : }
2309 : 4143494 : else if (note && GET_CODE (XEXP (note, 0)) == CONST
2310 : 10333 : && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
2311 : 10158 : && GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0)) == SYMBOL_REF
2312 : 10139 : && 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 : 78895 : if (sym != NULL_RTX)
2319 : : {
2320 : 78895 : move2add_record_sym_value (dst, sym, off);
2321 : 78895 : return;
2322 : : }
2323 : : }
2324 : :
2325 : 26277853 : if (GET_CODE (set) == SET
2326 : 25726901 : && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
2327 : 25725499 : && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
2328 : : {
2329 : 25721843 : rtx src = SET_SRC (set);
2330 : 25721843 : rtx base_reg;
2331 : 25721843 : unsigned HOST_WIDE_INT offset;
2332 : 25721843 : int base_regno;
2333 : :
2334 : 25721843 : switch (GET_CODE (src))
2335 : : {
2336 : 5741379 : case PLUS:
2337 : 5741379 : if (REG_P (XEXP (src, 0)))
2338 : : {
2339 : 5442736 : base_reg = XEXP (src, 0);
2340 : :
2341 : 5442736 : if (CONST_INT_P (XEXP (src, 1)))
2342 : 4709982 : offset = UINTVAL (XEXP (src, 1));
2343 : 732754 : else if (REG_P (XEXP (src, 1))
2344 : 732754 : && move2add_valid_value_p (REGNO (XEXP (src, 1)), mode))
2345 : : {
2346 : 80984 : if (reg_base_reg[REGNO (XEXP (src, 1))] < 0
2347 : 80984 : && reg_symbol_ref[REGNO (XEXP (src, 1))] == NULL_RTX)
2348 : 7153 : offset = reg_offset[REGNO (XEXP (src, 1))];
2349 : : /* Maybe the first register is known to be a
2350 : : constant. */
2351 : 73831 : else if (move2add_valid_value_p (REGNO (base_reg), mode)
2352 : 18405 : && reg_base_reg[REGNO (base_reg)] < 0
2353 : 74777 : && reg_symbol_ref[REGNO (base_reg)] == NULL_RTX)
2354 : : {
2355 : 807 : offset = reg_offset[REGNO (base_reg)];
2356 : 807 : base_reg = XEXP (src, 1);
2357 : : }
2358 : : else
2359 : 73024 : goto invalidate;
2360 : : }
2361 : : else
2362 : 651770 : goto invalidate;
2363 : :
2364 : : break;
2365 : : }
2366 : :
2367 : 298643 : goto invalidate;
2368 : :
2369 : : case REG:
2370 : : base_reg = src;
2371 : : offset = 0;
2372 : : break;
2373 : :
2374 : 4274678 : case CONST_INT:
2375 : : /* Start tracking the register as a constant. */
2376 : 4274678 : reg_base_reg[regno] = -1;
2377 : 4274678 : reg_symbol_ref[regno] = NULL_RTX;
2378 : 4274678 : reg_offset[regno] = INTVAL (SET_SRC (set));
2379 : : /* We assign the same luid to all registers set to constants. */
2380 : 4274678 : reg_set_luid[regno] = move2add_last_label_luid + 1;
2381 : 4274678 : move2add_record_mode (dst);
2382 : 4274678 : return;
2383 : :
2384 : 11139201 : default:
2385 : 11139201 : goto invalidate;
2386 : : }
2387 : :
2388 : 9284527 : 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 : 9284527 : if (!move2add_valid_value_p (base_regno, mode))
2393 : : {
2394 : 6736796 : reg_base_reg[base_regno] = base_regno;
2395 : 6736796 : reg_symbol_ref[base_regno] = NULL_RTX;
2396 : 6736796 : reg_offset[base_regno] = 0;
2397 : 6736796 : reg_set_luid[base_regno] = move2add_luid;
2398 : 6736796 : gcc_assert (GET_MODE (base_reg) == mode);
2399 : 6736796 : move2add_record_mode (base_reg);
2400 : : }
2401 : :
2402 : : /* Copy base information from our base register. */
2403 : 9284527 : reg_set_luid[regno] = reg_set_luid[base_regno];
2404 : 9284527 : reg_base_reg[regno] = reg_base_reg[base_regno];
2405 : 9284527 : reg_symbol_ref[regno] = reg_symbol_ref[base_regno];
2406 : :
2407 : : /* Compute the sum of the offsets or constants. */
2408 : 9284527 : reg_offset[regno]
2409 : 9284527 : = trunc_int_for_mode (offset + reg_offset[base_regno], mode);
2410 : :
2411 : 9284527 : move2add_record_mode (dst);
2412 : 9284527 : }
2413 : : else
2414 : : {
2415 : 556010 : invalidate:
2416 : : /* Invalidate the contents of the register. */
2417 : 28622477 : move2add_record_mode (dst);
2418 : 28622477 : 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 : 283157 : pass_postreload_cse (gcc::context *ctxt)
2441 : 566314 : : rtl_opt_pass (pass_data_postreload_cse, ctxt)
2442 : : {}
2443 : :
2444 : : /* opt_pass methods: */
2445 : 1435849 : bool gate (function *) final override
2446 : : {
2447 : 1435849 : 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 : 1008570 : pass_postreload_cse::execute (function *fun)
2456 : : {
2457 : 1008570 : if (!dbg_cnt (postreload_cse))
2458 : : return 0;
2459 : :
2460 : : /* Do a very simple CSE pass over just the hard registers. */
2461 : 1008570 : reload_cse_regs (get_insns ());
2462 : : /* Reload_cse_regs can eliminate potentially-trapping MEMs.
2463 : : Remove any EH edges associated with them. */
2464 : 1008570 : if (fun->can_throw_non_call_exceptions
2465 : 1008570 : && purge_all_dead_edges ())
2466 : 102 : cleanup_cfg (0);
2467 : :
2468 : : return 0;
2469 : : }
2470 : :
2471 : : } // anon namespace
2472 : :
2473 : : rtl_opt_pass *
2474 : 283157 : make_pass_postreload_cse (gcc::context *ctxt)
2475 : : {
2476 : 283157 : return new pass_postreload_cse (ctxt);
2477 : : }
|