Branch data Line data Source code
1 : : /* Subroutines used by or related to instruction recognition.
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 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "backend.h"
25 : : #include "target.h"
26 : : #include "rtl.h"
27 : : #include "tree.h"
28 : : #include "stmt.h"
29 : : #include "cfghooks.h"
30 : : #include "df.h"
31 : : #include "memmodel.h"
32 : : #include "tm_p.h"
33 : : #include "insn-config.h"
34 : : #include "regs.h"
35 : : #include "emit-rtl.h"
36 : : #include "recog.h"
37 : : #include "insn-attr.h"
38 : : #include "addresses.h"
39 : : #include "cfgrtl.h"
40 : : #include "cfgbuild.h"
41 : : #include "cfgcleanup.h"
42 : : #include "reload.h"
43 : : #include "tree-pass.h"
44 : : #include "function-abi.h"
45 : : #include "rtl-iter.h"
46 : :
47 : : #ifndef STACK_POP_CODE
48 : : #if STACK_GROWS_DOWNWARD
49 : : #define STACK_POP_CODE POST_INC
50 : : #else
51 : : #define STACK_POP_CODE POST_DEC
52 : : #endif
53 : : #endif
54 : :
55 : : static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx_insn *, bool);
56 : : static void validate_replace_src_1 (rtx *, void *);
57 : : static rtx_insn *split_insn (rtx_insn *);
58 : :
59 : : struct target_recog default_target_recog;
60 : : #if SWITCHABLE_TARGET
61 : : struct target_recog *this_target_recog = &default_target_recog;
62 : : #endif
63 : :
64 : : /* Nonzero means allow operands to be volatile.
65 : : This should be 0 if you are generating rtl, such as if you are calling
66 : : the functions in optabs.cc and expmed.cc (most of the time).
67 : : This should be 1 if all valid insns need to be recognized,
68 : : such as in reginfo.cc and final.cc and reload.cc.
69 : :
70 : : init_recog and init_recog_no_volatile are responsible for setting this. */
71 : :
72 : : int volatile_ok;
73 : :
74 : : struct recog_data_d recog_data;
75 : :
76 : : /* Contains a vector of operand_alternative structures, such that
77 : : operand OP of alternative A is at index A * n_operands + OP.
78 : : Set up by preprocess_constraints. */
79 : : const operand_alternative *recog_op_alt;
80 : :
81 : : /* Used to provide recog_op_alt for asms. */
82 : : static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS
83 : : * MAX_RECOG_ALTERNATIVES];
84 : :
85 : : /* On return from `constrain_operands', indicate which alternative
86 : : was satisfied. */
87 : :
88 : : int which_alternative;
89 : :
90 : : /* True for inline asm operands with - constraint modifier. */
91 : : bool raw_constraint_p;
92 : :
93 : : /* Nonzero after end of reload pass.
94 : : Set to 1 or 0 by toplev.cc.
95 : : Controls the significance of (SUBREG (MEM)). */
96 : :
97 : : int reload_completed;
98 : :
99 : : /* Nonzero after thread_prologue_and_epilogue_insns has run. */
100 : : int epilogue_completed;
101 : :
102 : : /* Initialize data used by the function `recog'.
103 : : This must be called once in the compilation of a function
104 : : before any insn recognition may be done in the function. */
105 : :
106 : : void
107 : 7829760 : init_recog_no_volatile (void)
108 : : {
109 : 7829760 : volatile_ok = 0;
110 : 7829760 : }
111 : :
112 : : void
113 : 11645553 : init_recog (void)
114 : : {
115 : 11645553 : volatile_ok = 1;
116 : 11645553 : }
117 : :
118 : :
119 : : /* Return true if labels in asm operands BODY are LABEL_REFs. */
120 : :
121 : : static bool
122 : 104858124 : asm_labels_ok (rtx body)
123 : : {
124 : 104858124 : rtx asmop;
125 : 104858124 : int i;
126 : :
127 : 104858124 : asmop = extract_asm_operands (body);
128 : 104858124 : if (asmop == NULL_RTX)
129 : : return true;
130 : :
131 : 766965 : for (i = 0; i < ASM_OPERANDS_LABEL_LENGTH (asmop); i++)
132 : 7426 : if (GET_CODE (ASM_OPERANDS_LABEL (asmop, i)) != LABEL_REF)
133 : : return false;
134 : :
135 : : return true;
136 : : }
137 : :
138 : : /* Check that X is an insn-body for an `asm' with operands
139 : : and that the operands mentioned in it are legitimate. */
140 : :
141 : : bool
142 : 104858124 : check_asm_operands (rtx x)
143 : : {
144 : 104858124 : int noperands;
145 : 104858124 : rtx *operands;
146 : 104858124 : const char **constraints;
147 : 104858124 : int i;
148 : :
149 : 104858124 : if (!asm_labels_ok (x))
150 : : return false;
151 : :
152 : : /* Post-reload, be more strict with things. */
153 : 104858124 : if (reload_completed)
154 : : {
155 : : /* ??? Doh! We've not got the wrapping insn. Cook one up. */
156 : 30008 : rtx_insn *insn = make_insn_raw (x);
157 : 30008 : extract_insn (insn);
158 : 30008 : constrain_operands (1, get_enabled_alternatives (insn));
159 : 30008 : return which_alternative >= 0;
160 : : }
161 : :
162 : 104828116 : noperands = asm_noperands (x);
163 : 104828116 : if (noperands < 0)
164 : : return false;
165 : 715281 : if (noperands == 0)
166 : : return true;
167 : :
168 : 606826 : operands = XALLOCAVEC (rtx, noperands);
169 : 606826 : constraints = XALLOCAVEC (const char *, noperands);
170 : :
171 : 606826 : decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
172 : :
173 : 2916101 : for (i = 0; i < noperands; i++)
174 : : {
175 : 2578857 : const char *c = constraints[i];
176 : 2578857 : if (c[0] == '%')
177 : 12599 : c++;
178 : 2578857 : if (! asm_operand_ok (operands[i], c, constraints))
179 : : return false;
180 : : }
181 : :
182 : : return true;
183 : : }
184 : :
185 : : /* Static data for the next two routines. */
186 : :
187 : : struct change_t
188 : : {
189 : : rtx object;
190 : : int old_code;
191 : : int old_len;
192 : : bool unshare;
193 : : rtx *loc;
194 : : rtx old;
195 : : };
196 : :
197 : : static change_t *changes;
198 : : static int changes_allocated;
199 : :
200 : : static int num_changes = 0;
201 : : int undo_recog_changes::s_num_changes = 0;
202 : :
203 : : /* Validate a proposed change to OBJECT. LOC is the location in the rtl
204 : : at which NEW_RTX will be placed. If NEW_LEN is >= 0, XVECLEN (NEW_RTX, 0)
205 : : will also be changed to NEW_LEN, which is no greater than the current
206 : : XVECLEN. If OBJECT is zero, no validation is done, the change is
207 : : simply made.
208 : :
209 : : Two types of objects are supported: If OBJECT is a MEM, memory_address_p
210 : : will be called with the address and mode as parameters. If OBJECT is
211 : : an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with
212 : : the change in place.
213 : :
214 : : IN_GROUP is nonzero if this is part of a group of changes that must be
215 : : performed as a group. In that case, the changes will be stored. The
216 : : function `apply_change_group' will validate and apply the changes.
217 : :
218 : : If IN_GROUP is zero, this is a single change. Try to recognize the insn
219 : : or validate the memory reference with the change applied. If the result
220 : : is not valid for the machine, suppress the change and return false.
221 : : Otherwise, perform the change and return true. */
222 : :
223 : : static bool
224 : 1801754146 : validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group,
225 : : bool unshare, int new_len = -1)
226 : : {
227 : 1801754146 : gcc_assert (!undo_recog_changes::is_active ());
228 : 1801754146 : rtx old = *loc;
229 : :
230 : : /* Single-element parallels aren't valid and won't match anything.
231 : : Replace them with the single element. */
232 : 1801754146 : if (new_len == 1 && GET_CODE (new_rtx) == PARALLEL)
233 : : {
234 : 6465071 : new_rtx = XVECEXP (new_rtx, 0, 0);
235 : 6465071 : new_len = -1;
236 : : }
237 : :
238 : : /* When a change is part of a group, callers expect to be able to change
239 : : INSN_CODE after making the change and have the code reset to its old
240 : : value by a later cancel_changes. We therefore need to register group
241 : : changes even if they're no-ops. */
242 : 1801754146 : if (!in_group
243 : 210842178 : && (old == new_rtx || rtx_equal_p (old, new_rtx))
244 : 1994535698 : && (new_len < 0 || XVECLEN (new_rtx, 0) == new_len))
245 : : return true;
246 : :
247 : 1608972594 : gcc_assert ((in_group != 0 || num_changes == 0)
248 : : && (new_len < 0 || new_rtx == *loc));
249 : :
250 : 1608972594 : *loc = new_rtx;
251 : :
252 : : /* Save the information describing this change. */
253 : 1608972594 : if (num_changes >= changes_allocated)
254 : : {
255 : 169083 : if (changes_allocated == 0)
256 : : /* This value allows for repeated substitutions inside complex
257 : : indexed addresses, or changes in up to 5 insns. */
258 : 168274 : changes_allocated = MAX_RECOG_OPERANDS * 5;
259 : : else
260 : 809 : changes_allocated *= 2;
261 : :
262 : 169083 : changes = XRESIZEVEC (change_t, changes, changes_allocated);
263 : : }
264 : :
265 : 1608972594 : changes[num_changes].object = object;
266 : 1608972594 : changes[num_changes].loc = loc;
267 : 1608972594 : changes[num_changes].old = old;
268 : 1608972594 : changes[num_changes].old_len = (new_len >= 0 ? XVECLEN (new_rtx, 0) : -1);
269 : 1608972594 : changes[num_changes].unshare = unshare;
270 : :
271 : 1608972594 : if (new_len >= 0)
272 : 11597704 : XVECLEN (new_rtx, 0) = new_len;
273 : :
274 : 1608972594 : if (object && !MEM_P (object))
275 : : {
276 : : /* Set INSN_CODE to force rerecognition of insn. Save old code in
277 : : case invalid. */
278 : 1584367525 : changes[num_changes].old_code = INSN_CODE (object);
279 : 1584367525 : INSN_CODE (object) = -1;
280 : : }
281 : :
282 : 1608972594 : num_changes++;
283 : :
284 : : /* If we are making a group of changes, return 1. Otherwise, validate the
285 : : change group we made. */
286 : :
287 : 1608972594 : if (in_group)
288 : : return true;
289 : : else
290 : 18060626 : return apply_change_group ();
291 : : }
292 : :
293 : : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
294 : : UNSHARE to false. */
295 : :
296 : : bool
297 : 1496097358 : validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
298 : : {
299 : 1496097358 : return validate_change_1 (object, loc, new_rtx, in_group, false);
300 : : }
301 : :
302 : : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
303 : : UNSHARE to true. */
304 : :
305 : : bool
306 : 287594013 : validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
307 : : {
308 : 287594013 : return validate_change_1 (object, loc, new_rtx, in_group, true);
309 : : }
310 : :
311 : : /* Change XVECLEN (*LOC, 0) to NEW_LEN. OBJECT, IN_GROUP and the return
312 : : value are as for validate_change_1. */
313 : :
314 : : bool
315 : 18062775 : validate_change_xveclen (rtx object, rtx *loc, int new_len, bool in_group)
316 : : {
317 : 18062775 : return validate_change_1 (object, loc, *loc, in_group, false, new_len);
318 : : }
319 : :
320 : : /* Keep X canonicalized if some changes have made it non-canonical; only
321 : : modifies the operands of X, not (for example) its code. Simplifications
322 : : are not the job of this routine.
323 : :
324 : : Return true if anything was changed. */
325 : : bool
326 : 1852107 : canonicalize_change_group (rtx_insn *insn, rtx x)
327 : : {
328 : 1852107 : if (COMMUTATIVE_P (x)
329 : 1852107 : && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
330 : : {
331 : : /* Oops, the caller has made X no longer canonical.
332 : : Let's redo the changes in the correct order. */
333 : 96525 : rtx tem = XEXP (x, 0);
334 : 96525 : validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
335 : 96525 : validate_unshare_change (insn, &XEXP (x, 1), tem, 1);
336 : 96525 : return true;
337 : : }
338 : : else
339 : 1755582 : return false;
340 : : }
341 : :
342 : : /* Check if REG_INC argument in *data overlaps a stored REG. */
343 : :
344 : : static void
345 : 0 : check_invalid_inc_dec (rtx reg, const_rtx, void *data)
346 : : {
347 : 0 : rtx *pinc = (rtx *) data;
348 : 0 : if (*pinc == NULL_RTX || MEM_P (reg))
349 : : return;
350 : 0 : if (reg_overlap_mentioned_p (reg, *pinc))
351 : 0 : *pinc = NULL_RTX;
352 : : }
353 : :
354 : : /* This subroutine of apply_change_group verifies whether the changes to INSN
355 : : were valid; i.e. whether INSN can still be recognized.
356 : :
357 : : If IN_GROUP is true clobbers which have to be added in order to
358 : : match the instructions will be added to the current change group.
359 : : Otherwise the changes will take effect immediately. */
360 : :
361 : : bool
362 : 483518899 : insn_invalid_p (rtx_insn *insn, bool in_group)
363 : : {
364 : 483518899 : rtx pat = PATTERN (insn);
365 : 483518899 : int num_clobbers = 0;
366 : : /* If we are before reload and the pattern is a SET, see if we can add
367 : : clobbers. */
368 : 483518899 : int icode = recog (pat, insn,
369 : 483518899 : (GET_CODE (pat) == SET
370 : 402460520 : && ! reload_completed
371 : 369922145 : && ! reload_in_progress)
372 : : ? &num_clobbers : 0);
373 : 483518899 : bool is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
374 : :
375 : :
376 : : /* If this is an asm and the operand aren't legal, then fail. Likewise if
377 : : this is not an asm and the insn wasn't recognized. */
378 : 525993 : if ((is_asm && ! check_asm_operands (PATTERN (insn)))
379 : 483329690 : || (!is_asm && icode < 0))
380 : 17906333 : return true;
381 : :
382 : : /* If we have to add CLOBBERs, fail if we have to add ones that reference
383 : : hard registers since our callers can't know if they are live or not.
384 : : Otherwise, add them. */
385 : 465612566 : if (num_clobbers > 0)
386 : : {
387 : 1859 : rtx newpat;
388 : :
389 : 1859 : if (added_clobbers_hard_reg_p (icode))
390 : : return true;
391 : :
392 : 550 : newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
393 : 550 : XVECEXP (newpat, 0, 0) = pat;
394 : 550 : add_clobbers (newpat, icode);
395 : 550 : if (in_group)
396 : 549 : validate_change (insn, &PATTERN (insn), newpat, 1);
397 : : else
398 : 1 : PATTERN (insn) = pat = newpat;
399 : : }
400 : :
401 : : /* After reload, verify that all constraints are satisfied. */
402 : 465611257 : if (reload_completed)
403 : : {
404 : 32522846 : extract_insn (insn);
405 : :
406 : 32522846 : if (! constrain_operands (1, get_preferred_alternatives (insn)))
407 : : return true;
408 : : }
409 : :
410 : : /* Punt if REG_INC argument overlaps some stored REG. */
411 : 465587441 : for (rtx link = FIND_REG_INC_NOTE (insn, NULL_RTX);
412 : 465587441 : link; link = XEXP (link, 1))
413 : : if (REG_NOTE_KIND (link) == REG_INC)
414 : : {
415 : : rtx reg = XEXP (link, 0);
416 : : note_stores (insn, check_invalid_inc_dec, ®);
417 : : if (reg == NULL_RTX)
418 : : return true;
419 : : }
420 : :
421 : 465587441 : INSN_CODE (insn) = icode;
422 : 465587441 : return false;
423 : : }
424 : :
425 : : /* Return number of changes made and not validated yet. */
426 : : int
427 : 4865537 : num_changes_pending (void)
428 : : {
429 : 4865537 : return num_changes;
430 : : }
431 : :
432 : : /* Tentatively apply the changes numbered NUM and up.
433 : : Return true if all changes are valid, false otherwise. */
434 : :
435 : : bool
436 : 761296183 : verify_changes (int num)
437 : : {
438 : 761296183 : int i;
439 : 761296183 : rtx last_validated = NULL_RTX;
440 : :
441 : : /* The changes have been applied and all INSN_CODEs have been reset to force
442 : : rerecognition.
443 : :
444 : : The changes are valid if we aren't given an object, or if we are
445 : : given a MEM and it still is a valid address, or if this is in insn
446 : : and it is recognized. In the latter case, if reload has completed,
447 : : we also require that the operands meet the constraints for
448 : : the insn. */
449 : :
450 : 2233751005 : for (i = num; i < num_changes; i++)
451 : : {
452 : 1487026572 : rtx object = changes[i].object;
453 : :
454 : : /* If there is no object to test or if it is the same as the one we
455 : : already tested, ignore it. */
456 : 1487026572 : if (object == 0 || object == last_validated)
457 : 771719944 : continue;
458 : :
459 : 715306628 : if (MEM_P (object))
460 : : {
461 : 38344 : if (! memory_address_addr_space_p (GET_MODE (object),
462 : : XEXP (object, 0),
463 : 19172 : MEM_ADDR_SPACE (object)))
464 : : break;
465 : : }
466 : 715287456 : else if (/* changes[i].old might be zero, e.g. when putting a
467 : : REG_FRAME_RELATED_EXPR into a previously empty list. */
468 : 715287456 : changes[i].old
469 : 715287456 : && REG_P (changes[i].old)
470 : 235089820 : && asm_noperands (PATTERN (object)) > 0
471 : 715473660 : && register_asm_p (changes[i].old))
472 : : {
473 : : /* Don't allow changes of hard register operands to inline
474 : : assemblies if they have been defined as register asm ("x"). */
475 : : break;
476 : : }
477 : 715287455 : else if (DEBUG_INSN_P (object))
478 : 245802018 : continue;
479 : 469485437 : else if (insn_invalid_p (as_a <rtx_insn *> (object), true))
480 : : {
481 : 17362689 : rtx pat = PATTERN (object);
482 : :
483 : : /* Perhaps we couldn't recognize the insn because there were
484 : : extra CLOBBERs at the end. If so, try to re-recognize
485 : : without the last CLOBBER (later iterations will cause each of
486 : : them to be eliminated, in turn). But don't do this if we
487 : : have an ASM_OPERAND. */
488 : 17362689 : if (GET_CODE (pat) == PARALLEL
489 : 4148586 : && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
490 : 20328158 : && asm_noperands (PATTERN (object)) < 0)
491 : : {
492 : 2777909 : rtx newpat;
493 : :
494 : 2777909 : if (XVECLEN (pat, 0) == 2)
495 : 2361066 : newpat = XVECEXP (pat, 0, 0);
496 : : else
497 : : {
498 : 416843 : int j;
499 : :
500 : 416843 : newpat
501 : 416843 : = gen_rtx_PARALLEL (VOIDmode,
502 : : rtvec_alloc (XVECLEN (pat, 0) - 1));
503 : 1283537 : for (j = 0; j < XVECLEN (newpat, 0); j++)
504 : 866694 : XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j);
505 : : }
506 : :
507 : : /* Add a new change to this group to replace the pattern
508 : : with this new pattern. Then consider this change
509 : : as having succeeded. The change we added will
510 : : cause the entire call to fail if things remain invalid.
511 : :
512 : : Note that this can lose if a later change than the one
513 : : we are processing specified &XVECEXP (PATTERN (object), 0, X)
514 : : but this shouldn't occur. */
515 : :
516 : 2777909 : validate_change (object, &PATTERN (object), newpat, 1);
517 : 2777909 : continue;
518 : 2777909 : }
519 : 14584780 : else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
520 : 14571676 : || GET_CODE (pat) == VAR_LOCATION)
521 : : /* If this insn is a CLOBBER or USE, it is always valid, but is
522 : : never recognized. */
523 : 13104 : continue;
524 : : else
525 : : break;
526 : : }
527 : : last_validated = object;
528 : : }
529 : :
530 : 761296183 : return (i == num_changes);
531 : : }
532 : :
533 : : /* A group of changes has previously been issued with validate_change
534 : : and verified with verify_changes. Call df_insn_rescan for each of
535 : : the insn changed and clear num_changes. */
536 : :
537 : : void
538 : 755688160 : confirm_change_group (void)
539 : : {
540 : 755688160 : int i;
541 : 755688160 : rtx last_object = NULL;
542 : :
543 : 755688160 : gcc_assert (!undo_recog_changes::is_active ());
544 : 2237150729 : for (i = 0; i < num_changes; i++)
545 : : {
546 : 1481462569 : rtx object = changes[i].object;
547 : :
548 : 1481462569 : if (changes[i].unshare)
549 : 19472336 : *changes[i].loc = copy_rtx (*changes[i].loc);
550 : :
551 : : /* Avoid unnecessary rescanning when multiple changes to same instruction
552 : : are made. */
553 : 1481462569 : if (object)
554 : : {
555 : 1479139617 : if (object != last_object && last_object && INSN_P (last_object))
556 : 7307583 : df_insn_rescan (as_a <rtx_insn *> (last_object));
557 : : last_object = object;
558 : : }
559 : : }
560 : :
561 : 755688160 : if (last_object && INSN_P (last_object))
562 : 593489619 : df_insn_rescan (as_a <rtx_insn *> (last_object));
563 : 755688160 : num_changes = 0;
564 : 755688160 : }
565 : :
566 : : /* Apply a group of changes previously issued with `validate_change'.
567 : : If all changes are valid, call confirm_change_group and return true,
568 : : otherwise, call cancel_changes and return false. */
569 : :
570 : : bool
571 : 753990770 : apply_change_group (void)
572 : : {
573 : 753990770 : if (verify_changes (0))
574 : : {
575 : 742218373 : confirm_change_group ();
576 : 742218373 : return true;
577 : : }
578 : : else
579 : : {
580 : 11772397 : cancel_changes (0);
581 : 11772397 : return false;
582 : : }
583 : : }
584 : :
585 : :
586 : : /* Return the number of changes so far in the current group. */
587 : :
588 : : int
589 : 734598713 : num_validated_changes (void)
590 : : {
591 : 734598713 : return num_changes;
592 : : }
593 : :
594 : : /* Retract the changes numbered NUM and up. */
595 : :
596 : : void
597 : 167297902 : cancel_changes (int num)
598 : : {
599 : 167297902 : gcc_assert (!undo_recog_changes::is_active ());
600 : 167297902 : int i;
601 : :
602 : : /* Back out all the changes. Do this in the opposite order in which
603 : : they were made. */
604 : 294807927 : for (i = num_changes - 1; i >= num; i--)
605 : : {
606 : 127510025 : if (changes[i].old_len >= 0)
607 : 10729421 : XVECLEN (*changes[i].loc, 0) = changes[i].old_len;
608 : : else
609 : 116780604 : *changes[i].loc = changes[i].old;
610 : 127510025 : if (changes[i].object && !MEM_P (changes[i].object))
611 : 105247007 : INSN_CODE (changes[i].object) = changes[i].old_code;
612 : : }
613 : 167297902 : num_changes = num;
614 : 167297902 : }
615 : :
616 : : /* Swap the status of change NUM from being applied to not being applied,
617 : : or vice versa. */
618 : :
619 : : static void
620 : 46458006 : swap_change (int num)
621 : : {
622 : 46458006 : if (changes[num].old_len >= 0)
623 : 2042726 : std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len);
624 : : else
625 : 44415280 : std::swap (*changes[num].loc, changes[num].old);
626 : 46458006 : if (changes[num].object && !MEM_P (changes[num].object))
627 : : {
628 : 46458006 : std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
629 : 46458006 : if (recog_data.insn == changes[num].object)
630 : 8 : recog_data.insn = nullptr;
631 : : }
632 : 46458006 : }
633 : :
634 : 27027433 : undo_recog_changes::undo_recog_changes (int num)
635 : 27027433 : : m_old_num_changes (s_num_changes)
636 : : {
637 : 27027433 : gcc_assert (num <= num_changes - s_num_changes);
638 : 50256436 : for (int i = num_changes - s_num_changes - 1; i >= num; i--)
639 : 23229003 : swap_change (i);
640 : 27027433 : s_num_changes = num_changes - num;
641 : 27027433 : }
642 : :
643 : 27027433 : undo_recog_changes::~undo_recog_changes ()
644 : : {
645 : 50256436 : for (int i = num_changes - s_num_changes;
646 : 50256436 : i < num_changes - m_old_num_changes; ++i)
647 : 23229003 : swap_change (i);
648 : 27027433 : s_num_changes = m_old_num_changes;
649 : 27027433 : }
650 : :
651 : : /* Reduce conditional compilation elsewhere. */
652 : : /* A subroutine of validate_replace_rtx_1 that tries to simplify the resulting
653 : : rtx. */
654 : :
655 : : static void
656 : 12350284 : simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
657 : : machine_mode op0_mode)
658 : : {
659 : 12350284 : rtx x = *loc;
660 : 12350284 : enum rtx_code code = GET_CODE (x);
661 : 12350284 : rtx new_rtx = NULL_RTX;
662 : 12350284 : scalar_int_mode is_mode;
663 : :
664 : 12350284 : if (SWAPPABLE_OPERANDS_P (x)
665 : 12350284 : && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
666 : : {
667 : 437608 : validate_unshare_change (object, loc,
668 : 437608 : gen_rtx_fmt_ee (COMMUTATIVE_ARITH_P (x) ? code
669 : : : swap_condition (code),
670 : : GET_MODE (x), XEXP (x, 1),
671 : : XEXP (x, 0)), 1);
672 : 437608 : x = *loc;
673 : 437608 : code = GET_CODE (x);
674 : : }
675 : :
676 : : /* Canonicalize arithmetics with all constant operands. */
677 : 12350284 : switch (GET_RTX_CLASS (code))
678 : : {
679 : 832291 : case RTX_UNARY:
680 : 832291 : if (CONSTANT_P (XEXP (x, 0)))
681 : 578056 : new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0),
682 : : op0_mode);
683 : : break;
684 : 6389959 : case RTX_COMM_ARITH:
685 : 6389959 : case RTX_BIN_ARITH:
686 : 6389959 : if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
687 : 209336 : new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0),
688 : : XEXP (x, 1));
689 : : break;
690 : 107700 : case RTX_COMPARE:
691 : 107700 : case RTX_COMM_COMPARE:
692 : 107700 : if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
693 : 3008 : new_rtx = simplify_relational_operation (code, GET_MODE (x), op0_mode,
694 : : XEXP (x, 0), XEXP (x, 1));
695 : : break;
696 : : default:
697 : : break;
698 : : }
699 : 790400 : if (new_rtx)
700 : : {
701 : 758019 : validate_change (object, loc, new_rtx, 1);
702 : 758019 : return;
703 : : }
704 : :
705 : 11592265 : switch (code)
706 : : {
707 : 2188711 : case PLUS:
708 : : /* If we have a PLUS whose second operand is now a CONST_INT, use
709 : : simplify_gen_binary to try to simplify it.
710 : : ??? We may want later to remove this, once simplification is
711 : : separated from this function. */
712 : 2188711 : if (CONST_INT_P (XEXP (x, 1)) && XEXP (x, 1) == to)
713 : 190956 : validate_change (object, loc,
714 : : simplify_gen_binary
715 : 190956 : (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
716 : : break;
717 : 476507 : case MINUS:
718 : 476507 : if (CONST_SCALAR_INT_P (XEXP (x, 1)))
719 : 23005 : validate_change (object, loc,
720 : : simplify_gen_binary
721 : 23005 : (PLUS, GET_MODE (x), XEXP (x, 0),
722 : : simplify_gen_unary (NEG,
723 : : GET_MODE (x), XEXP (x, 1),
724 : 23005 : GET_MODE (x))), 1);
725 : : break;
726 : 190556 : case ZERO_EXTEND:
727 : 190556 : case SIGN_EXTEND:
728 : 190556 : if (GET_MODE (XEXP (x, 0)) == VOIDmode)
729 : : {
730 : 0 : new_rtx = simplify_gen_unary (code, GET_MODE (x), XEXP (x, 0),
731 : : op0_mode);
732 : : /* If any of the above failed, substitute in something that
733 : : we know won't be recognized. */
734 : 0 : if (!new_rtx)
735 : 0 : new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
736 : 0 : validate_change (object, loc, new_rtx, 1);
737 : : }
738 : : break;
739 : 128772 : case SUBREG:
740 : : /* All subregs possible to simplify should be simplified. */
741 : 257544 : new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
742 : 128772 : SUBREG_BYTE (x));
743 : :
744 : : /* Subregs of VOIDmode operands are incorrect. */
745 : 128772 : if (!new_rtx && GET_MODE (SUBREG_REG (x)) == VOIDmode)
746 : 2 : new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
747 : 2 : if (new_rtx)
748 : 104967 : validate_change (object, loc, new_rtx, 1);
749 : : break;
750 : 7162 : case ZERO_EXTRACT:
751 : 7162 : case SIGN_EXTRACT:
752 : : /* If we are replacing a register with memory, try to change the memory
753 : : to be the mode required for memory in extract operations (this isn't
754 : : likely to be an insertion operation; if it was, nothing bad will
755 : : happen, we might just fail in some cases). */
756 : :
757 : 7162 : if (MEM_P (XEXP (x, 0))
758 : 381 : && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &is_mode)
759 : 381 : && CONST_INT_P (XEXP (x, 1))
760 : 381 : && CONST_INT_P (XEXP (x, 2))
761 : 261 : && !mode_dependent_address_p (XEXP (XEXP (x, 0), 0),
762 : 280 : MEM_ADDR_SPACE (XEXP (x, 0)))
763 : 7423 : && !MEM_VOLATILE_P (XEXP (x, 0)))
764 : : {
765 : 261 : int pos = INTVAL (XEXP (x, 2));
766 : 261 : machine_mode new_mode = is_mode;
767 : 261 : if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
768 : 0 : new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
769 : 261 : else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
770 : 0 : new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
771 : 261 : scalar_int_mode wanted_mode = (new_mode == VOIDmode
772 : 261 : ? word_mode
773 : 261 : : as_a <scalar_int_mode> (new_mode));
774 : :
775 : : /* If we have a narrower mode, we can do something. */
776 : 783 : if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
777 : : {
778 : 0 : int offset = pos / BITS_PER_UNIT;
779 : 0 : rtx newmem;
780 : :
781 : : /* If the bytes and bits are counted differently, we
782 : : must adjust the offset. */
783 : 0 : if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
784 : : offset =
785 : : (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode) -
786 : : offset);
787 : :
788 : 0 : gcc_assert (GET_MODE_PRECISION (wanted_mode)
789 : : == GET_MODE_BITSIZE (wanted_mode));
790 : 0 : pos %= GET_MODE_BITSIZE (wanted_mode);
791 : :
792 : 0 : newmem = adjust_address_nv (XEXP (x, 0), wanted_mode, offset);
793 : :
794 : 0 : validate_change (object, &XEXP (x, 2), GEN_INT (pos), 1);
795 : 0 : validate_change (object, &XEXP (x, 0), newmem, 1);
796 : : }
797 : : }
798 : :
799 : : break;
800 : :
801 : : default:
802 : : break;
803 : : }
804 : : }
805 : :
806 : : /* Replace every occurrence of FROM in X with TO. Mark each change with
807 : : validate_change passing OBJECT. */
808 : :
809 : : static void
810 : 69043844 : validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx_insn *object,
811 : : bool simplify)
812 : : {
813 : 69043844 : int i, j;
814 : 69043844 : const char *fmt;
815 : 69043844 : rtx x = *loc;
816 : 69043844 : enum rtx_code code;
817 : 69043844 : machine_mode op0_mode = VOIDmode;
818 : 69043844 : int prev_changes = num_changes;
819 : :
820 : 69043844 : if (!x)
821 : : return;
822 : :
823 : 69043844 : code = GET_CODE (x);
824 : 69043844 : fmt = GET_RTX_FORMAT (code);
825 : 69043844 : if (fmt[0] == 'e')
826 : 24002088 : op0_mode = GET_MODE (XEXP (x, 0));
827 : :
828 : : /* X matches FROM if it is the same rtx or they are both referring to the
829 : : same register in the same mode. Avoid calling rtx_equal_p unless the
830 : : operands look similar. */
831 : :
832 : 69043844 : if (x == from
833 : 53355858 : || (REG_P (x) && REG_P (from)
834 : 15329421 : && GET_MODE (x) == GET_MODE (from)
835 : 9069326 : && REGNO (x) == REGNO (from))
836 : 122399699 : || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
837 : 9069323 : && rtx_equal_p (x, from)))
838 : : {
839 : 15687989 : validate_unshare_change (object, loc, to, 1);
840 : 15687989 : return;
841 : : }
842 : :
843 : : /* Call ourself recursively to perform the replacements.
844 : : We must not replace inside already replaced expression, otherwise we
845 : : get infinite recursion for replacements like (reg X)->(subreg (reg X))
846 : : so we must special case shared ASM_OPERANDS. */
847 : :
848 : 53355855 : if (GET_CODE (x) == PARALLEL)
849 : : {
850 : 1403132 : for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
851 : : {
852 : 1033210 : if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
853 : 22746 : && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
854 : : {
855 : : /* Verify that operands are really shared. */
856 : 187 : gcc_assert (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0)))
857 : : == ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP
858 : : (x, 0, j))));
859 : 187 : validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
860 : : from, to, object, simplify);
861 : : }
862 : : else
863 : 1033023 : validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
864 : : simplify);
865 : : }
866 : : }
867 : : else
868 : 135116216 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
869 : : {
870 : 82130283 : if (fmt[i] == 'e')
871 : 40910243 : validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
872 : 41220040 : else if (fmt[i] == 'E')
873 : 5968369 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
874 : 3227771 : validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object,
875 : : simplify);
876 : : }
877 : :
878 : : /* If we didn't substitute, there is nothing more to do. */
879 : 53355855 : if (num_changes == prev_changes)
880 : : return;
881 : :
882 : : /* ??? The regmove is no more, so is this aberration still necessary? */
883 : : /* Allow substituted expression to have different mode. This is used by
884 : : regmove to change mode of pseudo register. */
885 : 12350357 : if (fmt[0] == 'e' && GET_MODE (XEXP (x, 0)) != VOIDmode)
886 : 9487452 : op0_mode = GET_MODE (XEXP (x, 0));
887 : :
888 : : /* Do changes needed to keep rtx consistent. Don't do any other
889 : : simplifications, as it is not our job. */
890 : 12350357 : if (simplify)
891 : 12350284 : simplify_while_replacing (loc, to, object, op0_mode);
892 : : }
893 : :
894 : : /* Try replacing every occurrence of FROM in subexpression LOC of INSN
895 : : with TO. After all changes have been made, validate by seeing
896 : : if INSN is still valid. */
897 : :
898 : : bool
899 : 0 : validate_replace_rtx_subexp (rtx from, rtx to, rtx_insn *insn, rtx *loc)
900 : : {
901 : 0 : validate_replace_rtx_1 (loc, from, to, insn, true);
902 : 0 : return apply_change_group ();
903 : : }
904 : :
905 : : /* Try replacing every occurrence of FROM in INSN with TO. After all
906 : : changes have been made, validate by seeing if INSN is still valid. */
907 : :
908 : : bool
909 : 2074790 : validate_replace_rtx (rtx from, rtx to, rtx_insn *insn)
910 : : {
911 : 2074790 : validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
912 : 2074790 : return apply_change_group ();
913 : : }
914 : :
915 : : /* Try replacing every occurrence of FROM in WHERE with TO. Assume that WHERE
916 : : is a part of INSN. After all changes have been made, validate by seeing if
917 : : INSN is still valid.
918 : : validate_replace_rtx (from, to, insn) is equivalent to
919 : : validate_replace_rtx_part (from, to, &PATTERN (insn), insn). */
920 : :
921 : : bool
922 : 0 : validate_replace_rtx_part (rtx from, rtx to, rtx *where, rtx_insn *insn)
923 : : {
924 : 0 : validate_replace_rtx_1 (where, from, to, insn, true);
925 : 0 : return apply_change_group ();
926 : : }
927 : :
928 : : /* Same as above, but do not simplify rtx afterwards. */
929 : : bool
930 : 93 : validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
931 : : rtx_insn *insn)
932 : : {
933 : 93 : validate_replace_rtx_1 (where, from, to, insn, false);
934 : 93 : return apply_change_group ();
935 : :
936 : : }
937 : :
938 : : /* Try replacing every occurrence of FROM in INSN with TO. This also
939 : : will replace in REG_EQUAL and REG_EQUIV notes. */
940 : :
941 : : void
942 : 21 : validate_replace_rtx_group (rtx from, rtx to, rtx_insn *insn)
943 : : {
944 : 21 : rtx note;
945 : 21 : validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
946 : 28 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
947 : 7 : if (REG_NOTE_KIND (note) == REG_EQUAL
948 : 7 : || REG_NOTE_KIND (note) == REG_EQUIV)
949 : 0 : validate_replace_rtx_1 (&XEXP (note, 0), from, to, insn, true);
950 : 21 : }
951 : :
952 : : /* Function called by note_uses to replace used subexpressions. */
953 : : struct validate_replace_src_data
954 : : {
955 : : rtx from; /* Old RTX */
956 : : rtx to; /* New RTX */
957 : : rtx_insn *insn; /* Insn in which substitution is occurring. */
958 : : };
959 : :
960 : : static void
961 : 21797716 : validate_replace_src_1 (rtx *x, void *data)
962 : : {
963 : 21797716 : struct validate_replace_src_data *d
964 : : = (struct validate_replace_src_data *) data;
965 : :
966 : 21797716 : validate_replace_rtx_1 (x, d->from, d->to, d->insn, true);
967 : 21797716 : }
968 : :
969 : : /* Try replacing every occurrence of FROM in INSN with TO, avoiding
970 : : SET_DESTs. */
971 : :
972 : : void
973 : 15844960 : validate_replace_src_group (rtx from, rtx to, rtx_insn *insn)
974 : : {
975 : 15844960 : struct validate_replace_src_data d;
976 : :
977 : 15844960 : d.from = from;
978 : 15844960 : d.to = to;
979 : 15844960 : d.insn = insn;
980 : 15844960 : note_uses (&PATTERN (insn), validate_replace_src_1, &d);
981 : 15844960 : }
982 : :
983 : : /* Try simplify INSN.
984 : : Invoke simplify_rtx () on every SET_SRC and SET_DEST inside the INSN's
985 : : pattern and return true if something was simplified. */
986 : :
987 : : bool
988 : 0 : validate_simplify_insn (rtx_insn *insn)
989 : : {
990 : 0 : int i;
991 : 0 : rtx pat = NULL;
992 : 0 : rtx newpat = NULL;
993 : :
994 : 0 : pat = PATTERN (insn);
995 : :
996 : 0 : if (GET_CODE (pat) == SET)
997 : : {
998 : 0 : newpat = simplify_rtx (SET_SRC (pat));
999 : 0 : if (newpat && !rtx_equal_p (SET_SRC (pat), newpat))
1000 : 0 : validate_change (insn, &SET_SRC (pat), newpat, 1);
1001 : 0 : newpat = simplify_rtx (SET_DEST (pat));
1002 : 0 : if (newpat && !rtx_equal_p (SET_DEST (pat), newpat))
1003 : 0 : validate_change (insn, &SET_DEST (pat), newpat, 1);
1004 : : }
1005 : 0 : else if (GET_CODE (pat) == PARALLEL)
1006 : 0 : for (i = 0; i < XVECLEN (pat, 0); i++)
1007 : : {
1008 : 0 : rtx s = XVECEXP (pat, 0, i);
1009 : :
1010 : 0 : if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
1011 : : {
1012 : 0 : newpat = simplify_rtx (SET_SRC (s));
1013 : 0 : if (newpat && !rtx_equal_p (SET_SRC (s), newpat))
1014 : 0 : validate_change (insn, &SET_SRC (s), newpat, 1);
1015 : 0 : newpat = simplify_rtx (SET_DEST (s));
1016 : 0 : if (newpat && !rtx_equal_p (SET_DEST (s), newpat))
1017 : 0 : validate_change (insn, &SET_DEST (s), newpat, 1);
1018 : : }
1019 : : }
1020 : 0 : return ((num_changes_pending () > 0) && (apply_change_group () > 0));
1021 : : }
1022 : :
1023 : : /* Try to process the address of memory expression MEM. Return true on
1024 : : success; leave the caller to clean up on failure. */
1025 : :
1026 : : bool
1027 : 24310194 : insn_propagation::apply_to_mem_1 (rtx mem)
1028 : : {
1029 : 24310194 : auto old_num_changes = num_validated_changes ();
1030 : 24310194 : mem_depth += 1;
1031 : 24310194 : bool res = apply_to_rvalue_1 (&XEXP (mem, 0));
1032 : 24310194 : mem_depth -= 1;
1033 : 24310194 : if (!res)
1034 : : return false;
1035 : :
1036 : 24309302 : if (old_num_changes != num_validated_changes ()
1037 : 7745658 : && should_check_mems
1038 : 27608807 : && !check_mem (old_num_changes, mem))
1039 : : return false;
1040 : :
1041 : : return true;
1042 : : }
1043 : :
1044 : : /* Try to process the rvalue expression at *LOC. Return true on success;
1045 : : leave the caller to clean up on failure. */
1046 : :
1047 : : bool
1048 : 235705226 : insn_propagation::apply_to_rvalue_1 (rtx *loc)
1049 : : {
1050 : 235705226 : rtx x = *loc;
1051 : 235705226 : enum rtx_code code = GET_CODE (x);
1052 : 235705226 : machine_mode mode = GET_MODE (x);
1053 : :
1054 : 235705226 : auto old_num_changes = num_validated_changes ();
1055 : 235705226 : if (from
1056 : 224461256 : && GET_CODE (x) == GET_CODE (from)
1057 : 327411915 : && (REG_P (x)
1058 : 91706689 : ? REGNO (x) == REGNO (from)
1059 : 23298 : : rtx_equal_p (x, from)))
1060 : : {
1061 : : /* Don't replace register asms in asm statements; we mustn't
1062 : : change the user's register allocation. */
1063 : 59016133 : if (REG_P (x)
1064 : 58993318 : && HARD_REGISTER_P (x)
1065 : 18275622 : && register_asm_p (x)
1066 : 59018127 : && asm_noperands (PATTERN (insn)) > 0)
1067 : : return false;
1068 : :
1069 : 59014307 : rtx newval = to;
1070 : 59014307 : if (GET_MODE (x) != GET_MODE (from))
1071 : : {
1072 : 629995 : gcc_assert (REG_P (x) && HARD_REGISTER_P (x));
1073 : 629995 : if (REG_NREGS (x) != REG_NREGS (from)
1074 : 629995 : || !REG_CAN_CHANGE_MODE_P (REGNO (x), GET_MODE (from),
1075 : : GET_MODE (x)))
1076 : 340388 : return false;
1077 : :
1078 : : /* If the reference is paradoxical and the replacement
1079 : : value contains registers, we would need to check that the
1080 : : simplification below does not increase REG_NREGS for those
1081 : : registers either. It seems simpler to punt on nonconstant
1082 : : values instead. */
1083 : 547105 : if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (from))
1084 : 547105 : && !CONSTANT_P (to))
1085 : : return false;
1086 : :
1087 : 527042 : newval = simplify_subreg (GET_MODE (x), to, GET_MODE (from),
1088 : : subreg_lowpart_offset (GET_MODE (x),
1089 : : GET_MODE (from)));
1090 : 527042 : if (!newval)
1091 : : return false;
1092 : :
1093 : : /* Check that the simplification didn't just push an explicit
1094 : : subreg down into subexpressions. In particular, for a register
1095 : : R that has a fixed mode, such as the stack pointer, a subreg of:
1096 : :
1097 : : (plus:M (reg:M R) (const_int C))
1098 : :
1099 : : would be:
1100 : :
1101 : : (plus:N (subreg:N (reg:M R) ...) (const_int C'))
1102 : :
1103 : : But targets can legitimately assume that subregs of hard registers
1104 : : will not be created after RA (except in special circumstances,
1105 : : such as strict_low_part). */
1106 : 293791 : subrtx_iterator::array_type array;
1107 : 1202551 : FOR_EACH_SUBRTX (iter, array, newval, NONCONST)
1108 : 912944 : if (GET_CODE (*iter) == SUBREG)
1109 : 4184 : return false;
1110 : 293791 : }
1111 : :
1112 : 58673919 : if (should_unshare)
1113 : 58673919 : validate_unshare_change (insn, loc, newval, 1);
1114 : : else
1115 : 0 : validate_change (insn, loc, newval, 1);
1116 : 58673919 : if (mem_depth && !REG_P (newval) && !CONSTANT_P (newval))
1117 : : {
1118 : : /* We're substituting into an address, but TO will have the
1119 : : form expected outside an address. Canonicalize it if
1120 : : necessary. */
1121 : 3595741 : insn_propagation subprop (insn);
1122 : 3595741 : subprop.mem_depth += 1;
1123 : 3595741 : if (!subprop.apply_to_rvalue (loc))
1124 : 0 : gcc_unreachable ();
1125 : 3595741 : if (should_unshare
1126 : 3595741 : && num_validated_changes () != old_num_changes + 1)
1127 : : {
1128 : : /* TO is owned by someone else, so create a copy and
1129 : : return TO to its original form. */
1130 : 308829 : newval = copy_rtx (*loc);
1131 : 308829 : cancel_changes (old_num_changes);
1132 : 308829 : validate_change (insn, loc, newval, 1);
1133 : : }
1134 : : }
1135 : 58673919 : num_replacements += 1;
1136 : 58673919 : should_unshare = true;
1137 : 58673919 : result_flags |= UNSIMPLIFIED;
1138 : 58673919 : return true;
1139 : : }
1140 : :
1141 : : /* Recursively apply the substitution and see if we can simplify
1142 : : the result. This specifically shouldn't use simplify_gen_* for
1143 : : speculative simplifications, since we want to avoid generating new
1144 : : expressions where possible. */
1145 : 176689093 : auto old_result_flags = result_flags;
1146 : 176689093 : rtx newx = NULL_RTX;
1147 : 176689093 : bool recurse_p = false;
1148 : 176689093 : switch (GET_RTX_CLASS (code))
1149 : : {
1150 : 3175975 : case RTX_UNARY:
1151 : 3175975 : {
1152 : 3175975 : machine_mode op0_mode = GET_MODE (XEXP (x, 0));
1153 : 3175975 : if (!apply_to_rvalue_1 (&XEXP (x, 0)))
1154 : : return false;
1155 : 3136796 : if (from && old_num_changes == num_validated_changes ())
1156 : : return true;
1157 : :
1158 : 2510353 : newx = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
1159 : 2510353 : break;
1160 : : }
1161 : :
1162 : 45900448 : case RTX_BIN_ARITH:
1163 : 45900448 : case RTX_COMM_ARITH:
1164 : 45900448 : {
1165 : 45900448 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1166 : 45900448 : || !apply_to_rvalue_1 (&XEXP (x, 1)))
1167 : 450402 : return false;
1168 : 45450046 : if (from && old_num_changes == num_validated_changes ())
1169 : : return true;
1170 : :
1171 : 34702258 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
1172 : 34702258 : && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
1173 : 2659618 : newx = simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
1174 : : else
1175 : 32042640 : newx = simplify_binary_operation (code, mode,
1176 : : XEXP (x, 0), XEXP (x, 1));
1177 : : break;
1178 : : }
1179 : :
1180 : 6076120 : case RTX_COMPARE:
1181 : 6076120 : case RTX_COMM_COMPARE:
1182 : 6076120 : {
1183 : 12152586 : machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
1184 : 6076120 : ? GET_MODE (XEXP (x, 0))
1185 : 346 : : GET_MODE (XEXP (x, 1)));
1186 : 6076120 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1187 : 6076120 : || !apply_to_rvalue_1 (&XEXP (x, 1)))
1188 : 4369 : return false;
1189 : 6071751 : if (from && old_num_changes == num_validated_changes ())
1190 : : return true;
1191 : :
1192 : 5171180 : newx = simplify_relational_operation (code, mode, op_mode,
1193 : : XEXP (x, 0), XEXP (x, 1));
1194 : 5171180 : break;
1195 : : }
1196 : :
1197 : 5498799 : case RTX_TERNARY:
1198 : 5498799 : case RTX_BITFIELD_OPS:
1199 : 5498799 : {
1200 : 5498799 : machine_mode op0_mode = GET_MODE (XEXP (x, 0));
1201 : 5498799 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1202 : 5491359 : || !apply_to_rvalue_1 (&XEXP (x, 1))
1203 : 10967785 : || !apply_to_rvalue_1 (&XEXP (x, 2)))
1204 : 32202 : return false;
1205 : 5466597 : if (from && old_num_changes == num_validated_changes ())
1206 : : return true;
1207 : :
1208 : 5401602 : newx = simplify_ternary_operation (code, mode, op0_mode,
1209 : : XEXP (x, 0), XEXP (x, 1),
1210 : : XEXP (x, 2));
1211 : 5401602 : break;
1212 : : }
1213 : :
1214 : 10700895 : case RTX_EXTRA:
1215 : 10700895 : if (code == SUBREG)
1216 : : {
1217 : 2353633 : machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
1218 : 2353633 : if (!apply_to_rvalue_1 (&SUBREG_REG (x)))
1219 : : return false;
1220 : 2353625 : if (from && old_num_changes == num_validated_changes ())
1221 : : return true;
1222 : :
1223 : 1705366 : rtx inner = SUBREG_REG (x);
1224 : 1705366 : newx = simplify_subreg (mode, inner, inner_mode, SUBREG_BYTE (x));
1225 : : /* Reject the same cases that simplify_gen_subreg would. */
1226 : 1705366 : if (!newx
1227 : 1705366 : && (GET_CODE (inner) == SUBREG
1228 : 1063949 : || GET_CODE (inner) == CONCAT
1229 : 1052275 : || GET_MODE (inner) == VOIDmode
1230 : 1052274 : || !validate_subreg (mode, inner_mode,
1231 : 1052274 : inner, SUBREG_BYTE (x))))
1232 : : {
1233 : 11719 : failure_reason = "would create an invalid subreg";
1234 : 11719 : return false;
1235 : : }
1236 : : break;
1237 : : }
1238 : : else
1239 : : recurse_p = true;
1240 : : break;
1241 : :
1242 : 53775344 : case RTX_OBJ:
1243 : 53775344 : if (code == LO_SUM)
1244 : : {
1245 : 0 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1246 : 0 : || !apply_to_rvalue_1 (&XEXP (x, 1)))
1247 : 0 : return false;
1248 : 0 : if (from && old_num_changes == num_validated_changes ())
1249 : : return true;
1250 : :
1251 : : /* (lo_sum (high x) y) -> y where x and y have the same base. */
1252 : 0 : rtx op0 = XEXP (x, 0);
1253 : 0 : rtx op1 = XEXP (x, 1);
1254 : 0 : if (GET_CODE (op0) == HIGH)
1255 : : {
1256 : 0 : rtx base0, base1, offset0, offset1;
1257 : 0 : split_const (XEXP (op0, 0), &base0, &offset0);
1258 : 0 : split_const (op1, &base1, &offset1);
1259 : 0 : if (rtx_equal_p (base0, base1))
1260 : 0 : newx = op1;
1261 : : }
1262 : : }
1263 : 53775344 : else if (code == REG)
1264 : : {
1265 : 36860440 : if (from && REG_P (from) && reg_overlap_mentioned_p (x, from))
1266 : : {
1267 : 61157 : failure_reason = "inexact register overlap";
1268 : 61157 : return false;
1269 : : }
1270 : : }
1271 : 16914904 : else if (code == MEM)
1272 : 12728933 : return apply_to_mem_1 (x);
1273 : : else
1274 : : recurse_p = true;
1275 : : break;
1276 : :
1277 : : case RTX_CONST_OBJ:
1278 : : break;
1279 : :
1280 : 1419996 : case RTX_AUTOINC:
1281 : 1419996 : if (from && reg_overlap_mentioned_p (XEXP (x, 0), from))
1282 : : {
1283 : 0 : failure_reason = "is subject to autoinc";
1284 : 0 : return false;
1285 : : }
1286 : : recurse_p = true;
1287 : : break;
1288 : :
1289 : 0 : case RTX_MATCH:
1290 : 0 : case RTX_INSN:
1291 : 0 : gcc_unreachable ();
1292 : : }
1293 : :
1294 : 49479040 : if (recurse_p)
1295 : : {
1296 : 13953229 : const char *fmt = GET_RTX_FORMAT (code);
1297 : 31505580 : for (int i = 0; fmt[i]; i++)
1298 : 17668288 : switch (fmt[i])
1299 : : {
1300 : : case 'E':
1301 : 5779396 : for (int j = 0; j < XVECLEN (x, i); j++)
1302 : 4111318 : if (!apply_to_rvalue_1 (&XVECEXP (x, i, j)))
1303 : : return false;
1304 : : break;
1305 : :
1306 : 12200306 : case 'e':
1307 : 12200306 : if (XEXP (x, i) && !apply_to_rvalue_1 (&XEXP (x, i)))
1308 : : return false;
1309 : : break;
1310 : : }
1311 : : }
1312 : 136419839 : else if (newx && !rtx_equal_p (x, newx))
1313 : : {
1314 : : /* All substitutions made by OLD_NUM_CHANGES onwards have been
1315 : : simplified. */
1316 : 10771978 : result_flags = ((result_flags & ~UNSIMPLIFIED)
1317 : : | (old_result_flags & UNSIMPLIFIED));
1318 : :
1319 : 10771978 : if (should_note_simplifications)
1320 : 3855276 : note_simplification (old_num_changes, old_result_flags, x, newx);
1321 : :
1322 : : /* There's no longer any point unsharing the substitutions made
1323 : : for subexpressions, since we'll just copy this one instead. */
1324 : : bool unshare = false;
1325 : 21477037 : for (int i = old_num_changes; i < num_changes; ++i)
1326 : : {
1327 : 10705059 : unshare |= changes[i].unshare;
1328 : 10705059 : changes[i].unshare = false;
1329 : : }
1330 : 10771978 : if (unshare)
1331 : 10341440 : validate_unshare_change (insn, loc, newx, 1);
1332 : : else
1333 : 430538 : validate_change (insn, loc, newx, 1);
1334 : : }
1335 : :
1336 : : return true;
1337 : : }
1338 : :
1339 : : /* Try to process the lvalue expression at *LOC. Return true on success;
1340 : : leave the caller to clean up on failure. */
1341 : :
1342 : : bool
1343 : 63060216 : insn_propagation::apply_to_lvalue_1 (rtx dest)
1344 : : {
1345 : 63060216 : rtx old_dest = dest;
1346 : 63060216 : while (GET_CODE (dest) == SUBREG
1347 : 63245358 : || GET_CODE (dest) == ZERO_EXTRACT
1348 : 63245358 : || GET_CODE (dest) == STRICT_LOW_PART)
1349 : : {
1350 : 185142 : if (GET_CODE (dest) == ZERO_EXTRACT
1351 : 185142 : && (!apply_to_rvalue_1 (&XEXP (dest, 1))
1352 : 2599 : || !apply_to_rvalue_1 (&XEXP (dest, 2))))
1353 : 0 : return false;
1354 : 185142 : dest = XEXP (dest, 0);
1355 : : }
1356 : :
1357 : 63060216 : if (MEM_P (dest))
1358 : 11581261 : return apply_to_mem_1 (dest);
1359 : :
1360 : : /* Check whether the substitution is safe in the presence of this lvalue. */
1361 : 51478955 : if (!from
1362 : 51478955 : || dest == old_dest
1363 : 180919 : || !REG_P (dest)
1364 : 51659874 : || !reg_overlap_mentioned_p (dest, from))
1365 : 51378332 : return true;
1366 : :
1367 : 100623 : if (SUBREG_P (old_dest)
1368 : 96001 : && SUBREG_REG (old_dest) == dest
1369 : 196624 : && !read_modify_subreg_p (old_dest))
1370 : : return true;
1371 : :
1372 : 100346 : failure_reason = "is part of a read-write destination";
1373 : 100346 : return false;
1374 : : }
1375 : :
1376 : : /* Try to process the instruction pattern at *LOC. Return true on success;
1377 : : leave the caller to clean up on failure. */
1378 : :
1379 : : bool
1380 : 66406556 : insn_propagation::apply_to_pattern_1 (rtx *loc)
1381 : : {
1382 : 66406556 : rtx body = *loc;
1383 : 66406556 : switch (GET_CODE (body))
1384 : : {
1385 : 0 : case COND_EXEC:
1386 : 0 : return (apply_to_rvalue_1 (&COND_EXEC_TEST (body))
1387 : 0 : && apply_to_pattern_1 (&COND_EXEC_CODE (body)));
1388 : :
1389 : : case PARALLEL:
1390 : 14322206 : for (int i = 0; i < XVECLEN (body, 0); ++i)
1391 : : {
1392 : 9755651 : rtx *subloc = &XVECEXP (body, 0, i);
1393 : 9755651 : if (GET_CODE (*subloc) == SET)
1394 : : {
1395 : 5290680 : if (!apply_to_lvalue_1 (SET_DEST (*subloc)))
1396 : : return false;
1397 : : /* ASM_OPERANDS are shared between SETs in the same PARALLEL.
1398 : : Only process them on the first iteration. */
1399 : 680609 : if ((i == 0 || GET_CODE (SET_SRC (*subloc)) != ASM_OPERANDS)
1400 : 5845286 : && !apply_to_rvalue_1 (&SET_SRC (*subloc)))
1401 : : return false;
1402 : : }
1403 : : else
1404 : : {
1405 : 4464971 : if (!apply_to_pattern_1 (subloc))
1406 : : return false;
1407 : : }
1408 : : }
1409 : : return true;
1410 : :
1411 : 8045 : case ASM_OPERANDS:
1412 : 27670 : for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
1413 : 19845 : if (!apply_to_rvalue_1 (&ASM_OPERANDS_INPUT (body, i)))
1414 : : return false;
1415 : : return true;
1416 : :
1417 : 4329373 : case CLOBBER:
1418 : 4329373 : return apply_to_lvalue_1 (XEXP (body, 0));
1419 : :
1420 : 53440163 : case SET:
1421 : 53440163 : return (apply_to_lvalue_1 (SET_DEST (body))
1422 : 53440163 : && apply_to_rvalue_1 (&SET_SRC (body)));
1423 : :
1424 : 4009098 : default:
1425 : : /* All the other possibilities never store and can use a normal
1426 : : rtx walk. This includes:
1427 : :
1428 : : - USE
1429 : : - TRAP_IF
1430 : : - PREFETCH
1431 : : - UNSPEC
1432 : : - UNSPEC_VOLATILE. */
1433 : 4009098 : return apply_to_rvalue_1 (loc);
1434 : : }
1435 : : }
1436 : :
1437 : : /* Apply this insn_propagation object's simplification or substitution
1438 : : to the instruction pattern at LOC. */
1439 : :
1440 : : bool
1441 : 61941585 : insn_propagation::apply_to_pattern (rtx *loc)
1442 : : {
1443 : 61941585 : unsigned int num_changes = num_validated_changes ();
1444 : 61941585 : bool res = apply_to_pattern_1 (loc);
1445 : 61941585 : if (!res)
1446 : 2331785 : cancel_changes (num_changes);
1447 : 61941585 : return res;
1448 : : }
1449 : :
1450 : : /* Apply this insn_propagation object's simplification or substitution
1451 : : to the rvalue expression at LOC. */
1452 : :
1453 : : bool
1454 : 7376478 : insn_propagation::apply_to_rvalue (rtx *loc)
1455 : : {
1456 : 7376478 : unsigned int num_changes = num_validated_changes ();
1457 : 7376478 : bool res = apply_to_rvalue_1 (loc);
1458 : 7376478 : if (!res)
1459 : 20245 : cancel_changes (num_changes);
1460 : 7376478 : return res;
1461 : : }
1462 : :
1463 : : /* Like apply_to_rvalue, but specifically for the case where *LOC is in
1464 : : a note. This never changes the INSN_CODE. */
1465 : :
1466 : : bool
1467 : 173370 : insn_propagation::apply_to_note (rtx *loc)
1468 : : {
1469 : 173370 : auto old_code = INSN_CODE (insn);
1470 : 173370 : bool res = apply_to_rvalue (loc);
1471 : 173370 : if (INSN_CODE (insn) != old_code)
1472 : 96189 : INSN_CODE (insn) = old_code;
1473 : 173370 : return res;
1474 : : }
1475 : :
1476 : : /* Check whether INSN matches a specific alternative of an .md pattern. */
1477 : :
1478 : : bool
1479 : 0 : valid_insn_p (rtx_insn *insn)
1480 : : {
1481 : 0 : recog_memoized (insn);
1482 : 0 : if (INSN_CODE (insn) < 0)
1483 : : return false;
1484 : 0 : extract_insn (insn);
1485 : : /* We don't know whether the insn will be in code that is optimized
1486 : : for size or speed, so consider all enabled alternatives. */
1487 : 0 : if (!constrain_operands (1, get_enabled_alternatives (insn)))
1488 : : return false;
1489 : : return true;
1490 : : }
1491 : :
1492 : : /* Return true if OP is a valid general operand for machine mode MODE.
1493 : : This is either a register reference, a memory reference,
1494 : : or a constant. In the case of a memory reference, the address
1495 : : is checked for general validity for the target machine.
1496 : :
1497 : : Register and memory references must have mode MODE in order to be valid,
1498 : : but some constants have no machine mode and are valid for any mode.
1499 : :
1500 : : If MODE is VOIDmode, OP is checked for validity for whatever mode
1501 : : it has.
1502 : :
1503 : : The main use of this function is as a predicate in match_operand
1504 : : expressions in the machine description. */
1505 : :
1506 : : bool
1507 : 4922018890 : general_operand (rtx op, machine_mode mode)
1508 : : {
1509 : 4922018890 : enum rtx_code code = GET_CODE (op);
1510 : :
1511 : 4922018890 : if (mode == VOIDmode)
1512 : 1278467906 : mode = GET_MODE (op);
1513 : :
1514 : : /* Don't accept CONST_INT or anything similar
1515 : : if the caller wants something floating. */
1516 : 4922018890 : if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1517 : 225543213 : && GET_MODE_CLASS (mode) != MODE_INT
1518 : 7153 : && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1519 : : return false;
1520 : :
1521 : 4922011737 : if (CONST_INT_P (op)
1522 : 275323758 : && mode != VOIDmode
1523 : 5144304863 : && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1524 : : return false;
1525 : :
1526 : 4922011523 : if (CONSTANT_P (op))
1527 : 63212738 : return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
1528 : 7398 : || mode == VOIDmode)
1529 : 339137313 : && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
1530 : 730818674 : && targetm.legitimate_constant_p (mode == VOIDmode
1531 : 53106969 : ? GET_MODE (op)
1532 : : : mode, op));
1533 : :
1534 : : /* Except for certain constants with VOIDmode, already checked for,
1535 : : OP's mode must match MODE if MODE specifies a mode. */
1536 : :
1537 : 4582866812 : if (GET_MODE (op) != mode)
1538 : : return false;
1539 : :
1540 : 4529182653 : if (code == SUBREG)
1541 : : {
1542 : 33384000 : rtx sub = SUBREG_REG (op);
1543 : :
1544 : : #ifdef INSN_SCHEDULING
1545 : : /* On machines that have insn scheduling, we want all memory
1546 : : reference to be explicit, so outlaw paradoxical SUBREGs.
1547 : : However, we must allow them after reload so that they can
1548 : : get cleaned up by cleanup_subreg_operands. */
1549 : 33333164 : if (!reload_completed && MEM_P (sub)
1550 : 33428597 : && paradoxical_subreg_p (op))
1551 : : return false;
1552 : : #endif
1553 : : /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
1554 : : may result in incorrect reference. We should simplify all valid
1555 : : subregs of MEM anyway. But allow this after reload because we
1556 : : might be called from cleanup_subreg_operands.
1557 : :
1558 : : ??? This is a kludge. */
1559 : 33339444 : if (!reload_completed
1560 : 33288608 : && maybe_ne (SUBREG_BYTE (op), 0)
1561 : 38643351 : && MEM_P (sub))
1562 : : return false;
1563 : :
1564 : 33339444 : if (REG_P (sub)
1565 : 31753780 : && REGNO (sub) < FIRST_PSEUDO_REGISTER
1566 : 5140 : && !REG_CAN_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
1567 : 0 : && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
1568 : 0 : && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
1569 : : /* LRA can generate some invalid SUBREGS just for matched
1570 : : operand reload presentation. LRA needs to treat them as
1571 : : valid. */
1572 : 33339444 : && ! LRA_SUBREG_P (op))
1573 : : return false;
1574 : :
1575 : : /* FLOAT_MODE subregs can't be paradoxical. Combine will occasionally
1576 : : create such rtl, and we must reject it. */
1577 : 33339444 : if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
1578 : : /* LRA can use subreg to store a floating point value in an
1579 : : integer mode. Although the floating point and the
1580 : : integer modes need the same number of hard registers, the
1581 : : size of floating point mode can be less than the integer
1582 : : mode. */
1583 : 323104 : && ! lra_in_progress
1584 : 33645255 : && paradoxical_subreg_p (op))
1585 : : return false;
1586 : :
1587 : 33339444 : op = sub;
1588 : 33339444 : code = GET_CODE (op);
1589 : : }
1590 : :
1591 : 4529138097 : if (code == REG)
1592 : 3687089444 : return (REGNO (op) >= FIRST_PSEUDO_REGISTER
1593 : 3687089444 : || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
1594 : :
1595 : 842048653 : if (code == MEM)
1596 : : {
1597 : 750825210 : rtx y = XEXP (op, 0);
1598 : :
1599 : 750825210 : if (! volatile_ok && MEM_VOLATILE_P (op))
1600 : : return false;
1601 : :
1602 : : /* Use the mem's mode, since it will be reloaded thus. LRA can
1603 : : generate move insn with invalid addresses which is made valid
1604 : : and efficiently calculated by LRA through further numerous
1605 : : transformations. */
1606 : 749982830 : if (lra_in_progress
1607 : 801812011 : || memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
1608 : 731713665 : return true;
1609 : : }
1610 : :
1611 : : return false;
1612 : : }
1613 : :
1614 : : /* Return true if OP is a valid memory address for a memory reference
1615 : : of mode MODE.
1616 : :
1617 : : The main use of this function is as a predicate in match_operand
1618 : : expressions in the machine description. */
1619 : :
1620 : : bool
1621 : 115475140 : address_operand (rtx op, machine_mode mode)
1622 : : {
1623 : : /* Wrong mode for an address expr. */
1624 : 115475140 : if (GET_MODE (op) != VOIDmode
1625 : 102990287 : && ! SCALAR_INT_MODE_P (GET_MODE (op)))
1626 : : return false;
1627 : :
1628 : 114791454 : return memory_address_p (mode, op);
1629 : : }
1630 : :
1631 : : /* Return true if OP is a register reference of mode MODE.
1632 : : If MODE is VOIDmode, accept a register in any mode.
1633 : :
1634 : : The main use of this function is as a predicate in match_operand
1635 : : expressions in the machine description. */
1636 : :
1637 : : bool
1638 : 2632112976 : register_operand (rtx op, machine_mode mode)
1639 : : {
1640 : 2632112976 : if (GET_CODE (op) == SUBREG)
1641 : : {
1642 : 11590932 : rtx sub = SUBREG_REG (op);
1643 : :
1644 : : /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
1645 : : because it is guaranteed to be reloaded into one.
1646 : : Just make sure the MEM is valid in itself.
1647 : : (Ideally, (SUBREG (MEM)...) should not exist after reload,
1648 : : but currently it does result from (SUBREG (REG)...) where the
1649 : : reg went on the stack.) */
1650 : 11590932 : if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
1651 : : return false;
1652 : : }
1653 : 2620522044 : else if (!REG_P (op))
1654 : : return false;
1655 : 1930232217 : return general_operand (op, mode);
1656 : : }
1657 : :
1658 : : /* Return true for a register in Pmode; ignore the tested mode. */
1659 : :
1660 : : bool
1661 : 0 : pmode_register_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1662 : : {
1663 : 0 : return register_operand (op, Pmode);
1664 : : }
1665 : :
1666 : : /* Return true if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
1667 : : or a hard register. */
1668 : :
1669 : : bool
1670 : 793524 : scratch_operand (rtx op, machine_mode mode)
1671 : : {
1672 : 793524 : if (GET_MODE (op) != mode && mode != VOIDmode)
1673 : : return false;
1674 : :
1675 : 755104 : return (GET_CODE (op) == SCRATCH
1676 : 755104 : || (REG_P (op)
1677 : 87656 : && (lra_in_progress
1678 : 71974 : || (REGNO (op) < FIRST_PSEUDO_REGISTER
1679 : 70644 : && REGNO_REG_CLASS (REGNO (op)) != NO_REGS))));
1680 : : }
1681 : :
1682 : : /* Return true if OP is a valid immediate operand for mode MODE.
1683 : :
1684 : : The main use of this function is as a predicate in match_operand
1685 : : expressions in the machine description. */
1686 : :
1687 : : bool
1688 : 506750735 : immediate_operand (rtx op, machine_mode mode)
1689 : : {
1690 : : /* Don't accept CONST_INT or anything similar
1691 : : if the caller wants something floating. */
1692 : 506750735 : if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1693 : 146644599 : && GET_MODE_CLASS (mode) != MODE_INT
1694 : 0 : && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1695 : : return false;
1696 : :
1697 : 506750735 : if (CONST_INT_P (op)
1698 : 327513050 : && mode != VOIDmode
1699 : 650238375 : && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1700 : : return false;
1701 : :
1702 : 506537601 : return (CONSTANT_P (op)
1703 : 392878398 : && (GET_MODE (op) == mode || mode == VOIDmode
1704 : 147896805 : || GET_MODE (op) == VOIDmode)
1705 : 390394621 : && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
1706 : 1113836179 : && targetm.legitimate_constant_p (mode == VOIDmode
1707 : 221535931 : ? GET_MODE (op)
1708 : : : mode, op));
1709 : : }
1710 : :
1711 : : /* Return true if OP is an operand that is a CONST_INT of mode MODE. */
1712 : :
1713 : : bool
1714 : 34521846 : const_int_operand (rtx op, machine_mode mode)
1715 : : {
1716 : 34521846 : if (!CONST_INT_P (op))
1717 : : return false;
1718 : :
1719 : 28504665 : if (mode != VOIDmode
1720 : 28504665 : && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1721 : : return false;
1722 : :
1723 : : return true;
1724 : : }
1725 : :
1726 : : #if TARGET_SUPPORTS_WIDE_INT
1727 : : /* Return true if OP is an operand that is a CONST_INT or CONST_WIDE_INT
1728 : : of mode MODE. */
1729 : : bool
1730 : 2420811 : const_scalar_int_operand (rtx op, machine_mode mode)
1731 : : {
1732 : 2420811 : if (!CONST_SCALAR_INT_P (op))
1733 : : return false;
1734 : :
1735 : 2059680 : if (CONST_INT_P (op))
1736 : 159733 : return const_int_operand (op, mode);
1737 : :
1738 : 1899947 : if (mode != VOIDmode)
1739 : : {
1740 : 1899947 : scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
1741 : 1899947 : int prec = GET_MODE_PRECISION (int_mode);
1742 : 1899947 : int bitsize = GET_MODE_BITSIZE (int_mode);
1743 : :
1744 : 1899947 : if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
1745 : : return false;
1746 : :
1747 : 1899947 : if (prec == bitsize)
1748 : : return true;
1749 : : else
1750 : : {
1751 : : /* Multiword partial int. */
1752 : 5496 : HOST_WIDE_INT x
1753 : 5496 : = CONST_WIDE_INT_ELT (op, CONST_WIDE_INT_NUNITS (op) - 1);
1754 : 5496 : return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
1755 : : }
1756 : : }
1757 : : return true;
1758 : : }
1759 : :
1760 : : /* Return true if OP is an operand that is a constant integer or constant
1761 : : floating-point number of MODE. */
1762 : :
1763 : : bool
1764 : 0 : const_double_operand (rtx op, machine_mode mode)
1765 : : {
1766 : 0 : return (GET_CODE (op) == CONST_DOUBLE)
1767 : 0 : && (GET_MODE (op) == mode || mode == VOIDmode);
1768 : : }
1769 : : #else
1770 : : /* Return true if OP is an operand that is a constant integer or constant
1771 : : floating-point number of MODE. */
1772 : :
1773 : : bool
1774 : : const_double_operand (rtx op, machine_mode mode)
1775 : : {
1776 : : /* Don't accept CONST_INT or anything similar
1777 : : if the caller wants something floating. */
1778 : : if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1779 : : && GET_MODE_CLASS (mode) != MODE_INT
1780 : : && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1781 : : return false;
1782 : :
1783 : : return ((CONST_DOUBLE_P (op) || CONST_INT_P (op))
1784 : : && (mode == VOIDmode || GET_MODE (op) == mode
1785 : : || GET_MODE (op) == VOIDmode));
1786 : : }
1787 : : #endif
1788 : : /* Return true if OP is a general operand that is not an immediate
1789 : : operand of mode MODE. */
1790 : :
1791 : : bool
1792 : 1916857222 : nonimmediate_operand (rtx op, machine_mode mode)
1793 : : {
1794 : 1916857222 : return (general_operand (op, mode) && ! CONSTANT_P (op));
1795 : : }
1796 : :
1797 : : /* Return true if OP is a register reference or
1798 : : immediate value of mode MODE. */
1799 : :
1800 : : bool
1801 : 518932217 : nonmemory_operand (rtx op, machine_mode mode)
1802 : : {
1803 : 518932217 : if (CONSTANT_P (op))
1804 : 32128337 : return immediate_operand (op, mode);
1805 : 486803880 : return register_operand (op, mode);
1806 : : }
1807 : :
1808 : : /* Return true if OP is a valid operand that stands for pushing a
1809 : : value of mode MODE onto the stack.
1810 : :
1811 : : The main use of this function is as a predicate in match_operand
1812 : : expressions in the machine description. */
1813 : :
1814 : : bool
1815 : 857276911 : push_operand (rtx op, machine_mode mode)
1816 : : {
1817 : 857276911 : if (!MEM_P (op))
1818 : : return false;
1819 : :
1820 : 256645647 : if (mode != VOIDmode && GET_MODE (op) != mode)
1821 : : return false;
1822 : :
1823 : 486943322 : poly_int64 rounded_size = GET_MODE_SIZE (mode);
1824 : :
1825 : : #ifdef PUSH_ROUNDING
1826 : 243471661 : rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
1827 : : #endif
1828 : :
1829 : 243471661 : op = XEXP (op, 0);
1830 : :
1831 : 486943322 : if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
1832 : : {
1833 : 207263652 : if (GET_CODE (op) != STACK_PUSH_CODE)
1834 : : return false;
1835 : : }
1836 : : else
1837 : : {
1838 : 36208009 : poly_int64 offset;
1839 : 36208009 : if (GET_CODE (op) != PRE_MODIFY
1840 : 1170264 : || GET_CODE (XEXP (op, 1)) != PLUS
1841 : 1170264 : || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
1842 : 1170264 : || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
1843 : 36208009 : || (STACK_GROWS_DOWNWARD
1844 : 1170264 : ? maybe_ne (offset, -rounded_size)
1845 : : : maybe_ne (offset, rounded_size)))
1846 : 813206613 : return false;
1847 : : }
1848 : :
1849 : 44070298 : return XEXP (op, 0) == stack_pointer_rtx;
1850 : : }
1851 : :
1852 : : /* Return true if OP is a valid operand that stands for popping a
1853 : : value of mode MODE off the stack.
1854 : :
1855 : : The main use of this function is as a predicate in match_operand
1856 : : expressions in the machine description. */
1857 : :
1858 : : bool
1859 : 308373549 : pop_operand (rtx op, machine_mode mode)
1860 : : {
1861 : 308373549 : if (!MEM_P (op))
1862 : : return false;
1863 : :
1864 : 76342584 : if (mode != VOIDmode && GET_MODE (op) != mode)
1865 : : return false;
1866 : :
1867 : 76342584 : op = XEXP (op, 0);
1868 : :
1869 : 76342584 : if (GET_CODE (op) != STACK_POP_CODE)
1870 : : return false;
1871 : :
1872 : 1393434 : return XEXP (op, 0) == stack_pointer_rtx;
1873 : : }
1874 : :
1875 : : /* Return true if ADDR is a valid memory address
1876 : : for mode MODE in address space AS. */
1877 : :
1878 : : bool
1879 : 1482608641 : memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr,
1880 : : addr_space_t as, code_helper ch ATTRIBUTE_UNUSED)
1881 : : {
1882 : : #ifdef GO_IF_LEGITIMATE_ADDRESS
1883 : : gcc_assert (ADDR_SPACE_GENERIC_P (as));
1884 : : GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
1885 : : return false;
1886 : :
1887 : : win:
1888 : : return true;
1889 : : #else
1890 : 1482608641 : return targetm.addr_space.legitimate_address_p (mode, addr, 0, as, ch);
1891 : : #endif
1892 : : }
1893 : :
1894 : : /* Return true if OP is a valid memory reference with mode MODE,
1895 : : including a valid address.
1896 : :
1897 : : The main use of this function is as a predicate in match_operand
1898 : : expressions in the machine description. */
1899 : :
1900 : : bool
1901 : 1231676025 : memory_operand (rtx op, machine_mode mode)
1902 : : {
1903 : 1231676025 : rtx inner;
1904 : :
1905 : 1231676025 : if (! reload_completed)
1906 : : /* Note that no SUBREG is a memory operand before end of reload pass,
1907 : : because (SUBREG (MEM...)) forces reloading into a register. */
1908 : 122575099 : return MEM_P (op) && general_operand (op, mode);
1909 : :
1910 : 1109100926 : if (mode != VOIDmode && GET_MODE (op) != mode)
1911 : : return false;
1912 : :
1913 : 811655137 : inner = op;
1914 : 811655137 : if (GET_CODE (inner) == SUBREG)
1915 : 8552 : inner = SUBREG_REG (inner);
1916 : :
1917 : 811655137 : return (MEM_P (inner) && general_operand (op, mode));
1918 : : }
1919 : :
1920 : : /* Return true if OP is a valid indirect memory reference with mode MODE;
1921 : : that is, a memory reference whose address is a general_operand. */
1922 : :
1923 : : bool
1924 : 0 : indirect_operand (rtx op, machine_mode mode)
1925 : : {
1926 : : /* Before reload, a SUBREG isn't in memory (see memory_operand, above). */
1927 : 0 : if (! reload_completed
1928 : 0 : && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
1929 : : {
1930 : 0 : if (mode != VOIDmode && GET_MODE (op) != mode)
1931 : : return false;
1932 : :
1933 : : /* The only way that we can have a general_operand as the resulting
1934 : : address is if OFFSET is zero and the address already is an operand
1935 : : or if the address is (plus Y (const_int -OFFSET)) and Y is an
1936 : : operand. */
1937 : 0 : poly_int64 offset;
1938 : 0 : rtx addr = strip_offset (XEXP (SUBREG_REG (op), 0), &offset);
1939 : 0 : return (known_eq (offset + SUBREG_BYTE (op), 0)
1940 : 0 : && general_operand (addr, Pmode));
1941 : : }
1942 : :
1943 : 0 : return (MEM_P (op)
1944 : 0 : && memory_operand (op, mode)
1945 : 0 : && general_operand (XEXP (op, 0), Pmode));
1946 : : }
1947 : :
1948 : : /* Return true if this is an ordered comparison operator (not including
1949 : : ORDERED and UNORDERED). */
1950 : :
1951 : : bool
1952 : 28368725 : ordered_comparison_operator (rtx op, machine_mode mode)
1953 : : {
1954 : 28368725 : if (mode != VOIDmode && GET_MODE (op) != mode)
1955 : : return false;
1956 : 28368725 : switch (GET_CODE (op))
1957 : : {
1958 : : case EQ:
1959 : : case NE:
1960 : : case LT:
1961 : : case LTU:
1962 : : case LE:
1963 : : case LEU:
1964 : : case GT:
1965 : : case GTU:
1966 : : case GE:
1967 : : case GEU:
1968 : : return true;
1969 : : default:
1970 : : return false;
1971 : : }
1972 : : }
1973 : :
1974 : : /* Return true if this is a comparison operator. This allows the use of
1975 : : MATCH_OPERATOR to recognize all the branch insns. */
1976 : :
1977 : : bool
1978 : 115529083 : comparison_operator (rtx op, machine_mode mode)
1979 : : {
1980 : 4765123 : return ((mode == VOIDmode || GET_MODE (op) == mode)
1981 : 119919355 : && COMPARISON_P (op));
1982 : : }
1983 : :
1984 : : /* If BODY is an insn body that uses ASM_OPERANDS, return it. */
1985 : :
1986 : : rtx
1987 : 1987684776 : extract_asm_operands (rtx body)
1988 : : {
1989 : 1987684776 : rtx tmp;
1990 : 1987684776 : switch (GET_CODE (body))
1991 : : {
1992 : : case ASM_OPERANDS:
1993 : : return body;
1994 : :
1995 : 1527162902 : case SET:
1996 : : /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */
1997 : 1527162902 : tmp = SET_SRC (body);
1998 : 1527162902 : if (GET_CODE (tmp) == ASM_OPERANDS)
1999 : : return tmp;
2000 : : break;
2001 : :
2002 : 331170619 : case PARALLEL:
2003 : 331170619 : tmp = XVECEXP (body, 0, 0);
2004 : 331170619 : if (GET_CODE (tmp) == ASM_OPERANDS)
2005 : : return tmp;
2006 : 329080830 : if (GET_CODE (tmp) == SET)
2007 : : {
2008 : 325296936 : tmp = SET_SRC (tmp);
2009 : 325296936 : if (GET_CODE (tmp) == ASM_OPERANDS)
2010 : : return tmp;
2011 : : }
2012 : : break;
2013 : :
2014 : : default:
2015 : : break;
2016 : : }
2017 : 1982313007 : return NULL;
2018 : : }
2019 : :
2020 : : /* If BODY is an insn body that uses ASM_OPERANDS,
2021 : : return the number of operands (both input and output) in the insn.
2022 : : If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
2023 : : return 0.
2024 : : Otherwise return -1. */
2025 : :
2026 : : int
2027 : 1520843063 : asm_noperands (const_rtx body)
2028 : : {
2029 : 1520843063 : rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
2030 : 1520843063 : int i, n_sets = 0;
2031 : :
2032 : 1520843063 : if (asm_op == NULL)
2033 : : {
2034 : 1516559263 : if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
2035 : 240406459 : && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
2036 : : {
2037 : : /* body is [(asm_input ...) (clobber (reg ...))...]. */
2038 : 56709 : for (i = XVECLEN (body, 0) - 1; i > 0; i--)
2039 : 37806 : if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
2040 : : return -1;
2041 : : return 0;
2042 : : }
2043 : : return -1;
2044 : : }
2045 : :
2046 : 4283800 : if (GET_CODE (body) == SET)
2047 : : n_sets = 1;
2048 : 4276339 : else if (GET_CODE (body) == PARALLEL)
2049 : : {
2050 : 4266298 : if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
2051 : : {
2052 : : /* Multiple output operands, or 1 output plus some clobbers:
2053 : : body is
2054 : : [(set OUTPUT (asm_operands ...))...
2055 : : (use (reg ...))...
2056 : : (clobber (reg ...))...]. */
2057 : : /* Count backwards through USEs and CLOBBERs to determine
2058 : : number of SETs. */
2059 : 5138664 : for (i = XVECLEN (body, 0); i > 0; i--)
2060 : : {
2061 : 5138664 : if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
2062 : : break;
2063 : 2590772 : if (GET_CODE (XVECEXP (body, 0, i - 1)) != USE
2064 : 2590772 : && GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
2065 : : return -1;
2066 : : }
2067 : :
2068 : : /* N_SETS is now number of output operands. */
2069 : 9906259 : n_sets = i;
2070 : :
2071 : : /* Verify that all the SETs we have
2072 : : came from a single original asm_operands insn
2073 : : (so that invalid combinations are blocked). */
2074 : 9906259 : for (i = 0; i < n_sets; i++)
2075 : : {
2076 : 7394891 : rtx elt = XVECEXP (body, 0, i);
2077 : 7394891 : if (GET_CODE (elt) != SET)
2078 : : return -1;
2079 : 7389971 : if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
2080 : : return -1;
2081 : : /* If these ASM_OPERANDS rtx's came from different original insns
2082 : : then they aren't allowed together. */
2083 : 7374965 : if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
2084 : 7374965 : != ASM_OPERANDS_INPUT_VEC (asm_op))
2085 : : return -1;
2086 : : }
2087 : : }
2088 : : else
2089 : : {
2090 : : /* 0 outputs, but some clobbers:
2091 : : body is [(asm_operands ...)
2092 : : (use (reg ...))...
2093 : : (clobber (reg ...))...]. */
2094 : : /* Make sure all the other parallel things really are clobbers. */
2095 : 5313281 : for (i = XVECLEN (body, 0) - 1; i > 0; i--)
2096 : 3597225 : if (GET_CODE (XVECEXP (body, 0, i)) != USE
2097 : 3597225 : && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
2098 : : return -1;
2099 : : }
2100 : : }
2101 : :
2102 : 4244926 : return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
2103 : 4244926 : + ASM_OPERANDS_LABEL_LENGTH (asm_op) + n_sets);
2104 : : }
2105 : :
2106 : : /* Assuming BODY is an insn body that uses ASM_OPERANDS,
2107 : : copy its operands (both input and output) into the vector OPERANDS,
2108 : : the locations of the operands within the insn into the vector OPERAND_LOCS,
2109 : : and the constraints for the operands into CONSTRAINTS.
2110 : : Write the modes of the operands into MODES.
2111 : : Write the location info into LOC.
2112 : : Return the assembler-template.
2113 : : If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
2114 : : return the basic assembly string.
2115 : :
2116 : : If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
2117 : : we don't store that info. */
2118 : :
2119 : : const char *
2120 : 1916036 : decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
2121 : : const char **constraints, machine_mode *modes,
2122 : : location_t *loc)
2123 : : {
2124 : 1916036 : int nbase = 0, n, i;
2125 : 1916036 : rtx asmop;
2126 : :
2127 : 1916036 : switch (GET_CODE (body))
2128 : : {
2129 : : case ASM_OPERANDS:
2130 : : /* Zero output asm: BODY is (asm_operands ...). */
2131 : : asmop = body;
2132 : : break;
2133 : :
2134 : 3569 : case SET:
2135 : : /* Single output asm: BODY is (set OUTPUT (asm_operands ...)). */
2136 : 3569 : asmop = SET_SRC (body);
2137 : :
2138 : : /* The output is in the SET.
2139 : : Its constraint is in the ASM_OPERANDS itself. */
2140 : 3569 : if (operands)
2141 : 3459 : operands[0] = SET_DEST (body);
2142 : 3569 : if (operand_locs)
2143 : 431 : operand_locs[0] = &SET_DEST (body);
2144 : 3569 : if (constraints)
2145 : 3459 : constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
2146 : 3569 : if (modes)
2147 : 431 : modes[0] = GET_MODE (SET_DEST (body));
2148 : : nbase = 1;
2149 : : break;
2150 : :
2151 : 1908246 : case PARALLEL:
2152 : 1908246 : {
2153 : 1908246 : int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */
2154 : :
2155 : 1908246 : asmop = XVECEXP (body, 0, 0);
2156 : 1908246 : if (GET_CODE (asmop) == SET)
2157 : : {
2158 : 1020104 : asmop = SET_SRC (asmop);
2159 : :
2160 : : /* At least one output, plus some CLOBBERs. The outputs are in
2161 : : the SETs. Their constraints are in the ASM_OPERANDS itself. */
2162 : 3803519 : for (i = 0; i < nparallel; i++)
2163 : : {
2164 : 3783256 : if (GET_CODE (XVECEXP (body, 0, i)) == USE
2165 : 3783256 : || GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
2166 : : break; /* Past last SET */
2167 : 2783415 : gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
2168 : 2783415 : if (operands)
2169 : 2624302 : operands[i] = SET_DEST (XVECEXP (body, 0, i));
2170 : 2783415 : if (operand_locs)
2171 : 887639 : operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
2172 : 2783415 : if (constraints)
2173 : 2638159 : constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
2174 : 2783415 : if (modes)
2175 : 887639 : modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
2176 : : }
2177 : : nbase = i;
2178 : : }
2179 : 888142 : else if (GET_CODE (asmop) == ASM_INPUT)
2180 : : {
2181 : 8914 : if (loc)
2182 : 0 : *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
2183 : 8914 : return XSTR (asmop, 0);
2184 : : }
2185 : : break;
2186 : : }
2187 : :
2188 : 0 : default:
2189 : 0 : gcc_unreachable ();
2190 : : }
2191 : :
2192 : 1907122 : n = ASM_OPERANDS_INPUT_LENGTH (asmop);
2193 : 3630881 : for (i = 0; i < n; i++)
2194 : : {
2195 : 1723759 : if (operand_locs)
2196 : 659307 : operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
2197 : 1723759 : if (operands)
2198 : 1597989 : operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
2199 : 1723759 : if (constraints)
2200 : 1615211 : constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
2201 : 1723759 : if (modes)
2202 : 659307 : modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
2203 : : }
2204 : 1907122 : nbase += n;
2205 : :
2206 : 1907122 : n = ASM_OPERANDS_LABEL_LENGTH (asmop);
2207 : 1924777 : for (i = 0; i < n; i++)
2208 : : {
2209 : 17655 : if (operand_locs)
2210 : 8892 : operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
2211 : 17655 : if (operands)
2212 : 15998 : operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
2213 : 17655 : if (constraints)
2214 : 16069 : constraints[nbase + i] = "";
2215 : 17655 : if (modes)
2216 : 8892 : modes[nbase + i] = Pmode;
2217 : : }
2218 : :
2219 : 1907122 : if (loc)
2220 : 103825 : *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
2221 : :
2222 : 1907122 : return ASM_OPERANDS_TEMPLATE (asmop);
2223 : : }
2224 : :
2225 : : /* Parse inline assembly string STRING and determine which operands are
2226 : : referenced by % markers. For the first NOPERANDS operands, set USED[I]
2227 : : to true if operand I is referenced.
2228 : :
2229 : : This is intended to distinguish barrier-like asms such as:
2230 : :
2231 : : asm ("" : "=m" (...));
2232 : :
2233 : : from real references such as:
2234 : :
2235 : : asm ("sw\t$0, %0" : "=m" (...)); */
2236 : :
2237 : : void
2238 : 0 : get_referenced_operands (const char *string, bool *used,
2239 : : unsigned int noperands)
2240 : : {
2241 : 0 : memset (used, 0, sizeof (bool) * noperands);
2242 : 0 : const char *p = string;
2243 : 0 : while (*p)
2244 : 0 : switch (*p)
2245 : : {
2246 : 0 : case '%':
2247 : 0 : p += 1;
2248 : : /* A letter followed by a digit indicates an operand number. */
2249 : 0 : if (ISALPHA (p[0]) && ISDIGIT (p[1]))
2250 : 0 : p += 1;
2251 : 0 : if (ISDIGIT (*p))
2252 : : {
2253 : 0 : char *endptr;
2254 : 0 : unsigned long opnum = strtoul (p, &endptr, 10);
2255 : 0 : if (endptr != p && opnum < noperands)
2256 : 0 : used[opnum] = true;
2257 : 0 : p = endptr;
2258 : : }
2259 : : else
2260 : 0 : p += 1;
2261 : : break;
2262 : :
2263 : 0 : default:
2264 : 0 : p++;
2265 : 0 : break;
2266 : : }
2267 : 0 : }
2268 : :
2269 : : /* Check if an asm_operand matches its constraints.
2270 : : Return > 0 if ok, = 0 if bad, < 0 if inconclusive. */
2271 : :
2272 : : int
2273 : 3235911 : asm_operand_ok (rtx op, const char *constraint, const char **constraints)
2274 : : {
2275 : 3235911 : int result = 0;
2276 : 3235911 : bool incdec_ok = false;
2277 : :
2278 : : /* Use constrain_operands after reload. */
2279 : 3235911 : gcc_assert (!reload_completed);
2280 : :
2281 : : /* Empty constraint string is the same as "X,...,X", i.e. X for as
2282 : : many alternatives as required to match the other operands. */
2283 : 3235911 : if (*constraint == '\0')
2284 : 3698 : result = 1;
2285 : :
2286 : 8940324 : while (*constraint)
2287 : : {
2288 : 5704415 : enum constraint_num cn;
2289 : 5704415 : char c = *constraint;
2290 : 5704415 : int len;
2291 : 5704415 : switch (c)
2292 : : {
2293 : 11497 : case ',':
2294 : 11497 : raw_constraint_p = false;
2295 : 11497 : constraint++;
2296 : 11497 : continue;
2297 : :
2298 : 605026 : case '0': case '1': case '2': case '3': case '4':
2299 : 605026 : case '5': case '6': case '7': case '8': case '9':
2300 : : /* If caller provided constraints pointer, look up
2301 : : the matching constraint. Otherwise, our caller should have
2302 : : given us the proper matching constraint, but we can't
2303 : : actually fail the check if they didn't. Indicate that
2304 : : results are inconclusive. */
2305 : 605026 : if (constraints)
2306 : : {
2307 : 604825 : char *end;
2308 : 604825 : unsigned long match;
2309 : :
2310 : 604825 : match = strtoul (constraint, &end, 10);
2311 : 604825 : if (!result)
2312 : 604564 : result = asm_operand_ok (op, constraints[match], NULL);
2313 : 604825 : constraint = (const char *) end;
2314 : : }
2315 : : else
2316 : : {
2317 : 225 : do
2318 : 225 : constraint++;
2319 : 225 : while (ISDIGIT (*constraint));
2320 : 201 : if (! result)
2321 : 174 : result = -1;
2322 : : }
2323 : 605026 : continue;
2324 : :
2325 : : /* The rest of the compiler assumes that reloading the address
2326 : : of a MEM into a register will make it fit an 'o' constraint.
2327 : : That is, if it sees a MEM operand for an 'o' constraint,
2328 : : it assumes that (mem (base-reg)) will fit.
2329 : :
2330 : : That assumption fails on targets that don't have offsettable
2331 : : addresses at all. We therefore need to treat 'o' asm
2332 : : constraints as a special case and only accept operands that
2333 : : are already offsettable, thus proving that at least one
2334 : : offsettable address exists. */
2335 : 36 : case 'o': /* offsettable */
2336 : 36 : if (offsettable_nonstrict_memref_p (op))
2337 : 2204025 : result = 1;
2338 : : break;
2339 : :
2340 : 96821 : case 'g':
2341 : 96821 : if (general_operand (op, VOIDmode))
2342 : 2204025 : result = 1;
2343 : : break;
2344 : :
2345 : 20 : case '-':
2346 : 20 : raw_constraint_p = true;
2347 : 20 : constraint++;
2348 : 20 : continue;
2349 : :
2350 : : case '<':
2351 : : case '>':
2352 : : /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
2353 : : to exist, excepting those that expand_call created. Further,
2354 : : on some machines which do not have generalized auto inc/dec,
2355 : : an inc/dec is not a memory_operand.
2356 : :
2357 : : Match any memory and hope things are resolved after reload. */
2358 : 4991015 : incdec_ok = true;
2359 : : /* FALLTHRU */
2360 : 4991015 : default:
2361 : 4991015 : cn = lookup_constraint (constraint);
2362 : 4991015 : rtx mem = NULL;
2363 : 4991015 : switch (get_constraint_type (cn))
2364 : : {
2365 : 4836413 : case CT_REGISTER:
2366 : 4836413 : if (!result
2367 : 2405414 : && (reg_class_for_constraint (cn) != NO_REGS
2368 : 2429030 : || constraint[0] == '{')
2369 : 2406066 : && GET_MODE (op) != BLKmode
2370 : 7242444 : && register_operand (op, VOIDmode))
2371 : : result = 1;
2372 : : break;
2373 : :
2374 : 4 : case CT_CONST_INT:
2375 : 4 : if (!result
2376 : 4 : && CONST_INT_P (op)
2377 : 6 : && insn_const_int_ok_for_constraint (INTVAL (op), cn))
2378 : : result = 1;
2379 : : break;
2380 : :
2381 : 134585 : case CT_MEMORY:
2382 : 134585 : case CT_RELAXED_MEMORY:
2383 : 134585 : mem = op;
2384 : : /* Fall through. */
2385 : 134585 : case CT_SPECIAL_MEMORY:
2386 : : /* Every memory operand can be reloaded to fit. */
2387 : 134585 : if (!mem)
2388 : 0 : mem = extract_mem_from_operand (op);
2389 : 134585 : result = result || memory_operand (mem, VOIDmode);
2390 : 134585 : break;
2391 : :
2392 : 143 : case CT_ADDRESS:
2393 : : /* Every address operand can be reloaded to fit. */
2394 : 143 : result = result || address_operand (op, VOIDmode);
2395 : 143 : break;
2396 : :
2397 : 19870 : case CT_FIXED_FORM:
2398 : 19870 : result = result || constraint_satisfied_p (op, cn);
2399 : 19870 : break;
2400 : : }
2401 : : break;
2402 : 616543 : }
2403 : 5087872 : len = CONSTRAINT_LEN (c, constraint);
2404 : 5091928 : do
2405 : 5091928 : constraint++;
2406 : 10179800 : while (--len && *constraint && *constraint != ',');
2407 : 5087872 : if (len)
2408 : : {
2409 : 2 : raw_constraint_p = false;
2410 : 2 : return 0;
2411 : : }
2412 : : }
2413 : 3235909 : raw_constraint_p = false;
2414 : :
2415 : : /* For operands without < or > constraints reject side-effects. */
2416 : 3235909 : if (AUTO_INC_DEC && !incdec_ok && result && MEM_P (op))
2417 : : switch (GET_CODE (XEXP (op, 0)))
2418 : : {
2419 : : case PRE_INC:
2420 : : case POST_INC:
2421 : : case PRE_DEC:
2422 : : case POST_DEC:
2423 : : case PRE_MODIFY:
2424 : : case POST_MODIFY:
2425 : : return 0;
2426 : : default:
2427 : : break;
2428 : : }
2429 : :
2430 : 3235909 : return result;
2431 : : }
2432 : :
2433 : : /* Given an rtx *P, if it is a sum containing an integer constant term,
2434 : : return the location (type rtx *) of the pointer to that constant term.
2435 : : Otherwise, return a null pointer. */
2436 : :
2437 : : rtx *
2438 : 40828036 : find_constant_term_loc (rtx *p)
2439 : : {
2440 : 40828036 : rtx *tem;
2441 : 40828036 : enum rtx_code code = GET_CODE (*p);
2442 : :
2443 : : /* If *P IS such a constant term, P is its location. */
2444 : :
2445 : 40828036 : if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
2446 : 29111939 : || code == CONST)
2447 : : return p;
2448 : :
2449 : : /* Otherwise, if not a sum, it has no constant term. */
2450 : :
2451 : 29064424 : if (GET_CODE (*p) != PLUS)
2452 : : return 0;
2453 : :
2454 : : /* If one of the summands is constant, return its location. */
2455 : :
2456 : 13631246 : if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
2457 : 0 : && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
2458 : : return p;
2459 : :
2460 : : /* Otherwise, check each summand for containing a constant term. */
2461 : :
2462 : 13631246 : if (XEXP (*p, 0) != 0)
2463 : : {
2464 : 13631246 : tem = find_constant_term_loc (&XEXP (*p, 0));
2465 : 13631246 : if (tem != 0)
2466 : : return tem;
2467 : : }
2468 : :
2469 : 13631246 : if (XEXP (*p, 1) != 0)
2470 : : {
2471 : 13631246 : tem = find_constant_term_loc (&XEXP (*p, 1));
2472 : 13631246 : if (tem != 0)
2473 : : return tem;
2474 : : }
2475 : :
2476 : : return 0;
2477 : : }
2478 : :
2479 : : /* Return true if OP is a memory reference whose address contains
2480 : : no side effects and remains valid after the addition of a positive
2481 : : integer less than the size of the object being referenced.
2482 : :
2483 : : We assume that the original address is valid and do not check it.
2484 : :
2485 : : This uses strict_memory_address_p as a subroutine, so
2486 : : don't use it before reload. */
2487 : :
2488 : : bool
2489 : 5518720 : offsettable_memref_p (rtx op)
2490 : : {
2491 : 5518720 : return ((MEM_P (op))
2492 : 11034157 : && offsettable_address_addr_space_p (1, GET_MODE (op), XEXP (op, 0),
2493 : 5515437 : MEM_ADDR_SPACE (op)));
2494 : : }
2495 : :
2496 : : /* Similar, but don't require a strictly valid mem ref:
2497 : : consider pseudo-regs valid as index or base regs. */
2498 : :
2499 : : bool
2500 : 12090023 : offsettable_nonstrict_memref_p (rtx op)
2501 : : {
2502 : 12090023 : return ((MEM_P (op))
2503 : 24180012 : && offsettable_address_addr_space_p (0, GET_MODE (op), XEXP (op, 0),
2504 : 12089989 : MEM_ADDR_SPACE (op)));
2505 : : }
2506 : :
2507 : : /* Return true if Y is a memory address which contains no side effects
2508 : : and would remain valid for address space AS after the addition of
2509 : : a positive integer less than the size of that mode.
2510 : :
2511 : : We assume that the original address is valid and do not check it.
2512 : : We do check that it is valid for narrower modes.
2513 : :
2514 : : If STRICTP is nonzero, we require a strictly valid address,
2515 : : for the sake of use in reload.cc. */
2516 : :
2517 : : bool
2518 : 17605426 : offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
2519 : : addr_space_t as)
2520 : : {
2521 : 17605426 : enum rtx_code ycode = GET_CODE (y);
2522 : 17605426 : rtx z;
2523 : 17605426 : rtx y1 = y;
2524 : 17605426 : rtx *y2;
2525 : 12089989 : bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
2526 : 17605426 : (strictp ? strict_memory_address_addr_space_p
2527 : : : memory_address_addr_space_p);
2528 : 35210852 : poly_int64 mode_sz = GET_MODE_SIZE (mode);
2529 : :
2530 : 17605426 : if (CONSTANT_ADDRESS_P (y))
2531 : : return true;
2532 : :
2533 : : /* Adjusting an offsettable address involves changing to a narrower mode.
2534 : : Make sure that's OK. */
2535 : :
2536 : 14939634 : if (mode_dependent_address_p (y, as))
2537 : : return false;
2538 : :
2539 : 14756468 : machine_mode address_mode = GET_MODE (y);
2540 : 14756468 : if (address_mode == VOIDmode)
2541 : 0 : address_mode = targetm.addr_space.address_mode (as);
2542 : : #ifdef POINTERS_EXTEND_UNSIGNED
2543 : 14756468 : machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
2544 : : #endif
2545 : :
2546 : : /* ??? How much offset does an offsettable BLKmode reference need?
2547 : : Clearly that depends on the situation in which it's being used.
2548 : : However, the current situation in which we test 0xffffffff is
2549 : : less than ideal. Caveat user. */
2550 : 14756468 : if (known_eq (mode_sz, 0))
2551 : 0 : mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
2552 : :
2553 : : /* If the expression contains a constant term,
2554 : : see if it remains valid when max possible offset is added. */
2555 : :
2556 : 14756468 : if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
2557 : : {
2558 : 11763612 : bool good;
2559 : :
2560 : 11763612 : y1 = *y2;
2561 : 11763612 : *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
2562 : : /* Use QImode because an odd displacement may be automatically invalid
2563 : : for any wider mode. But it should be valid for a single byte. */
2564 : 11763612 : good = (*addressp) (QImode, y, as, ERROR_MARK);
2565 : :
2566 : : /* In any case, restore old contents of memory. */
2567 : 11763612 : *y2 = y1;
2568 : 11763612 : return good;
2569 : : }
2570 : :
2571 : 2992856 : if (GET_RTX_CLASS (ycode) == RTX_AUTOINC)
2572 : : return false;
2573 : :
2574 : : /* The offset added here is chosen as the maximum offset that
2575 : : any instruction could need to add when operating on something
2576 : : of the specified mode. We assume that if Y and Y+c are
2577 : : valid addresses then so is Y+d for all 0<d<c. adjust_address will
2578 : : go inside a LO_SUM here, so we do so as well. */
2579 : 2992856 : if (GET_CODE (y) == LO_SUM
2580 : 0 : && mode != BLKmode
2581 : 2992856 : && known_le (mode_sz, GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT))
2582 : 0 : z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
2583 : : plus_constant (address_mode, XEXP (y, 1),
2584 : : mode_sz - 1));
2585 : : #ifdef POINTERS_EXTEND_UNSIGNED
2586 : : /* Likewise for a ZERO_EXTEND from pointer_mode. */
2587 : 2992856 : else if (POINTERS_EXTEND_UNSIGNED > 0
2588 : 2992856 : && GET_CODE (y) == ZERO_EXTEND
2589 : 13 : && GET_MODE (XEXP (y, 0)) == pointer_mode)
2590 : 7 : z = gen_rtx_ZERO_EXTEND (address_mode,
2591 : : plus_constant (pointer_mode, XEXP (y, 0),
2592 : : mode_sz - 1));
2593 : : #endif
2594 : : else
2595 : 2992849 : z = plus_constant (address_mode, y, mode_sz - 1);
2596 : :
2597 : : /* Use QImode because an odd displacement may be automatically invalid
2598 : : for any wider mode. But it should be valid for a single byte. */
2599 : 2992856 : return (*addressp) (QImode, z, as, ERROR_MARK);
2600 : : }
2601 : :
2602 : : /* Return true if ADDR is an address-expression whose effect depends
2603 : : on the mode of the memory reference it is used in.
2604 : :
2605 : : ADDRSPACE is the address space associated with the address.
2606 : :
2607 : : Autoincrement addressing is a typical example of mode-dependence
2608 : : because the amount of the increment depends on the mode. */
2609 : :
2610 : : bool
2611 : 40219230 : mode_dependent_address_p (rtx addr, addr_space_t addrspace)
2612 : : {
2613 : : /* Auto-increment addressing with anything other than post_modify
2614 : : or pre_modify always introduces a mode dependency. Catch such
2615 : : cases now instead of deferring to the target. */
2616 : 40219230 : if (GET_CODE (addr) == PRE_INC
2617 : 40219230 : || GET_CODE (addr) == POST_INC
2618 : 40219224 : || GET_CODE (addr) == PRE_DEC
2619 : 36449332 : || GET_CODE (addr) == POST_DEC)
2620 : : return true;
2621 : :
2622 : 36449332 : return targetm.mode_dependent_address_p (addr, addrspace);
2623 : : }
2624 : :
2625 : : /* Return true if boolean attribute ATTR is supported. */
2626 : :
2627 : : static bool
2628 : 1633564875 : have_bool_attr (bool_attr attr)
2629 : : {
2630 : 1633564875 : switch (attr)
2631 : : {
2632 : : case BA_ENABLED:
2633 : : return HAVE_ATTR_enabled;
2634 : : case BA_PREFERRED_FOR_SIZE:
2635 : : return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size;
2636 : : case BA_PREFERRED_FOR_SPEED:
2637 : : return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed;
2638 : : }
2639 : 0 : gcc_unreachable ();
2640 : : }
2641 : :
2642 : : /* Return the value of ATTR for instruction INSN. */
2643 : :
2644 : : static bool
2645 : 1728827996 : get_bool_attr (rtx_insn *insn, bool_attr attr)
2646 : : {
2647 : 1728827996 : switch (attr)
2648 : : {
2649 : 729058403 : case BA_ENABLED:
2650 : 729058403 : return get_attr_enabled (insn);
2651 : 363585228 : case BA_PREFERRED_FOR_SIZE:
2652 : 363585228 : return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
2653 : 636184365 : case BA_PREFERRED_FOR_SPEED:
2654 : 636184365 : return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn);
2655 : : }
2656 : 0 : gcc_unreachable ();
2657 : : }
2658 : :
2659 : : /* Like get_bool_attr_mask, but don't use the cache. */
2660 : :
2661 : : static alternative_mask
2662 : 103836527 : get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr)
2663 : : {
2664 : : /* Temporarily install enough information for get_attr_<foo> to assume
2665 : : that the insn operands are already cached. As above, the attribute
2666 : : mustn't depend on the values of operands, so we don't provide their
2667 : : real values here. */
2668 : 103836527 : rtx_insn *old_insn = recog_data.insn;
2669 : 103836527 : int old_alternative = which_alternative;
2670 : :
2671 : 103836527 : recog_data.insn = insn;
2672 : 103836527 : alternative_mask mask = ALL_ALTERNATIVES;
2673 : 103836527 : int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
2674 : 1832664523 : for (int i = 0; i < n_alternatives; i++)
2675 : : {
2676 : 1728827996 : which_alternative = i;
2677 : 1728827996 : if (!get_bool_attr (insn, attr))
2678 : 518482067 : mask &= ~ALTERNATIVE_BIT (i);
2679 : : }
2680 : :
2681 : 103836527 : recog_data.insn = old_insn;
2682 : 103836527 : which_alternative = old_alternative;
2683 : 103836527 : return mask;
2684 : : }
2685 : :
2686 : : /* Return the mask of operand alternatives that are allowed for INSN
2687 : : by boolean attribute ATTR. This mask depends only on INSN and on
2688 : : the current target; it does not depend on things like the values of
2689 : : operands. */
2690 : :
2691 : : static alternative_mask
2692 : 1635829035 : get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
2693 : : {
2694 : : /* Quick exit for asms and for targets that don't use these attributes. */
2695 : 1635829035 : int code = INSN_CODE (insn);
2696 : 1635829035 : if (code < 0 || !have_bool_attr (attr))
2697 : : return ALL_ALTERNATIVES;
2698 : :
2699 : : /* Calling get_attr_<foo> can be expensive, so cache the mask
2700 : : for speed. */
2701 : 1633564875 : if (!this_target_recog->x_bool_attr_masks[code][attr])
2702 : 12764064 : this_target_recog->x_bool_attr_masks[code][attr]
2703 : 12764064 : = get_bool_attr_mask_uncached (insn, attr);
2704 : 1633564875 : return this_target_recog->x_bool_attr_masks[code][attr];
2705 : : }
2706 : :
2707 : : /* Return the set of alternatives of INSN that are allowed by the current
2708 : : target. */
2709 : :
2710 : : alternative_mask
2711 : 1168053352 : get_enabled_alternatives (rtx_insn *insn)
2712 : : {
2713 : 1168053352 : return get_bool_attr_mask (insn, BA_ENABLED);
2714 : : }
2715 : :
2716 : : /* Return the set of alternatives of INSN that are allowed by the current
2717 : : target and are preferred for the current size/speed optimization
2718 : : choice. */
2719 : :
2720 : : alternative_mask
2721 : 467686666 : get_preferred_alternatives (rtx_insn *insn)
2722 : : {
2723 : 467686666 : if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
2724 : 411801020 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
2725 : : else
2726 : 55885646 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
2727 : : }
2728 : :
2729 : : /* Return the set of alternatives of INSN that are allowed by the current
2730 : : target and are preferred for the size/speed optimization choice
2731 : : associated with BB. Passing a separate BB is useful if INSN has not
2732 : : been emitted yet or if we are considering moving it to a different
2733 : : block. */
2734 : :
2735 : : alternative_mask
2736 : 89017 : get_preferred_alternatives (rtx_insn *insn, basic_block bb)
2737 : : {
2738 : 89017 : if (optimize_bb_for_speed_p (bb))
2739 : 83892 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
2740 : : else
2741 : 5125 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
2742 : : }
2743 : :
2744 : : /* Assert that the cached boolean attributes for INSN are still accurate.
2745 : : The backend is required to define these attributes in a way that only
2746 : : depends on the current target (rather than operands, compiler phase,
2747 : : etc.). */
2748 : :
2749 : : bool
2750 : 36606776 : check_bool_attrs (rtx_insn *insn)
2751 : : {
2752 : 36606776 : int code = INSN_CODE (insn);
2753 : 36606776 : if (code >= 0)
2754 : 146427104 : for (int i = 0; i <= BA_LAST; ++i)
2755 : : {
2756 : 109820328 : enum bool_attr attr = (enum bool_attr) i;
2757 : 109820328 : if (this_target_recog->x_bool_attr_masks[code][attr])
2758 : 91072463 : gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
2759 : : == get_bool_attr_mask_uncached (insn, attr));
2760 : : }
2761 : 36606776 : return true;
2762 : : }
2763 : :
2764 : : /* Like extract_insn, but save insn extracted and don't extract again, when
2765 : : called again for the same insn expecting that recog_data still contain the
2766 : : valid information. This is used primary by gen_attr infrastructure that
2767 : : often does extract insn again and again. */
2768 : : void
2769 : 10395205202 : extract_insn_cached (rtx_insn *insn)
2770 : : {
2771 : 10395205202 : if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
2772 : : return;
2773 : 761720429 : extract_insn (insn);
2774 : 761720429 : recog_data.insn = insn;
2775 : : }
2776 : :
2777 : : /* Do uncached extract_insn, constrain_operands and complain about failures.
2778 : : This should be used when extracting a pre-existing constrained instruction
2779 : : if the caller wants to know which alternative was chosen. */
2780 : : void
2781 : 265887816 : extract_constrain_insn (rtx_insn *insn)
2782 : : {
2783 : 265887816 : extract_insn (insn);
2784 : 265887816 : if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
2785 : 0 : fatal_insn_not_found (insn);
2786 : 265887816 : }
2787 : :
2788 : : /* Do cached extract_insn, constrain_operands and complain about failures.
2789 : : Used by insn_attrtab. */
2790 : : void
2791 : 9193033629 : extract_constrain_insn_cached (rtx_insn *insn)
2792 : : {
2793 : 9193033629 : extract_insn_cached (insn);
2794 : 9193033629 : if (which_alternative == -1
2795 : 9193033629 : && !constrain_operands (reload_completed,
2796 : : get_enabled_alternatives (insn)))
2797 : 0 : fatal_insn_not_found (insn);
2798 : 9193033629 : }
2799 : :
2800 : : /* Do cached constrain_operands on INSN and complain about failures. */
2801 : : bool
2802 : 333598255 : constrain_operands_cached (rtx_insn *insn, int strict)
2803 : : {
2804 : 333598255 : if (which_alternative == -1)
2805 : 92857597 : return constrain_operands (strict, get_enabled_alternatives (insn));
2806 : : else
2807 : : return true;
2808 : : }
2809 : :
2810 : : /* Analyze INSN and fill in recog_data. */
2811 : :
2812 : : void
2813 : 2047680788 : extract_insn (rtx_insn *insn)
2814 : : {
2815 : 2047680788 : int i;
2816 : 2047680788 : int icode;
2817 : 2047680788 : int noperands;
2818 : 2047680788 : rtx body = PATTERN (insn);
2819 : :
2820 : 2047680788 : recog_data.n_operands = 0;
2821 : 2047680788 : recog_data.n_alternatives = 0;
2822 : 2047680788 : recog_data.n_dups = 0;
2823 : 2047680788 : recog_data.is_asm = false;
2824 : :
2825 : 2047680788 : switch (GET_CODE (body))
2826 : : {
2827 : : case USE:
2828 : : case CLOBBER:
2829 : : case ASM_INPUT:
2830 : : case ADDR_VEC:
2831 : : case ADDR_DIFF_VEC:
2832 : : case VAR_LOCATION:
2833 : : case DEBUG_MARKER:
2834 : : return;
2835 : :
2836 : 1640572529 : case SET:
2837 : 1640572529 : if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
2838 : 376 : goto asm_insn;
2839 : : else
2840 : 1640572153 : goto normal_insn;
2841 : 213287381 : case PARALLEL:
2842 : 213287381 : if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
2843 : 209554373 : && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
2844 : 212929899 : || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
2845 : 212318998 : || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
2846 : 975658 : goto asm_insn;
2847 : : else
2848 : 212311723 : goto normal_insn;
2849 : 976156 : case ASM_OPERANDS:
2850 : 976156 : asm_insn:
2851 : 976156 : recog_data.n_operands = noperands = asm_noperands (body);
2852 : 976156 : if (noperands >= 0)
2853 : : {
2854 : : /* This insn is an `asm' with operands. */
2855 : :
2856 : : /* expand_asm_operands makes sure there aren't too many operands. */
2857 : 976156 : gcc_assert (noperands <= MAX_RECOG_OPERANDS);
2858 : :
2859 : : /* Now get the operand values and constraints out of the insn. */
2860 : 976156 : decode_asm_operands (body, recog_data.operand,
2861 : : recog_data.operand_loc,
2862 : : recog_data.constraints,
2863 : : recog_data.operand_mode, NULL);
2864 : 976156 : memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
2865 : 976156 : if (noperands > 0)
2866 : : {
2867 : 438134 : const char *p = recog_data.constraints[0];
2868 : 438134 : recog_data.n_alternatives = 1;
2869 : 1237849 : while (*p)
2870 : 799715 : recog_data.n_alternatives += (*p++ == ',');
2871 : : }
2872 : 976156 : recog_data.is_asm = true;
2873 : 976156 : break;
2874 : : }
2875 : 0 : fatal_insn_not_found (insn);
2876 : :
2877 : 1906492913 : default:
2878 : 1906492913 : normal_insn:
2879 : : /* Ordinary insn: recognize it, get the operands via insn_extract
2880 : : and get the constraints. */
2881 : :
2882 : 1906492913 : icode = recog_memoized (insn);
2883 : 1906492913 : if (icode < 0)
2884 : 0 : fatal_insn_not_found (insn);
2885 : :
2886 : 1906492913 : recog_data.n_operands = noperands = insn_data[icode].n_operands;
2887 : 1906492913 : recog_data.n_alternatives = insn_data[icode].n_alternatives;
2888 : 1906492913 : recog_data.n_dups = insn_data[icode].n_dups;
2889 : :
2890 : 1906492913 : insn_extract (insn);
2891 : :
2892 : 7871664805 : for (i = 0; i < noperands; i++)
2893 : : {
2894 : 4058678979 : recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
2895 : 4058678979 : recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
2896 : 4058678979 : recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
2897 : : /* VOIDmode match_operands gets mode from their real operand. */
2898 : 4058678979 : if (recog_data.operand_mode[i] == VOIDmode)
2899 : 398728059 : recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
2900 : : }
2901 : : }
2902 : 5967549254 : for (i = 0; i < noperands; i++)
2903 : 4060080185 : recog_data.operand_type[i]
2904 : 6574088747 : = (recog_data.constraints[i][0] == '=' ? OP_OUT
2905 : 2514008562 : : recog_data.constraints[i][0] == '+' ? OP_INOUT
2906 : : : OP_IN);
2907 : :
2908 : 1907469069 : gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES);
2909 : :
2910 : 1907469069 : recog_data.insn = NULL;
2911 : 1907469069 : which_alternative = -1;
2912 : : }
2913 : :
2914 : : /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS
2915 : : operands, N_ALTERNATIVES alternatives and constraint strings
2916 : : CONSTRAINTS. OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries
2917 : : and CONSTRAINTS has N_OPERANDS entries. OPLOC should be passed in
2918 : : if the insn is an asm statement and preprocessing should take the
2919 : : asm operands into account, e.g. to determine whether they could be
2920 : : addresses in constraints that require addresses; it should then
2921 : : point to an array of pointers to each operand. */
2922 : :
2923 : : void
2924 : 4697212 : preprocess_constraints (int n_operands, int n_alternatives,
2925 : : const char **constraints,
2926 : : operand_alternative *op_alt_base,
2927 : : rtx **oploc)
2928 : : {
2929 : 12055794 : for (int i = 0; i < n_operands; i++)
2930 : : {
2931 : 7358582 : int j;
2932 : 7358582 : struct operand_alternative *op_alt;
2933 : 7358582 : const char *p = constraints[i];
2934 : :
2935 : 7358582 : op_alt = op_alt_base;
2936 : :
2937 : 46440702 : for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
2938 : : {
2939 : 39082120 : op_alt[i].cl = NO_REGS;
2940 : 39082120 : op_alt[i].register_filters = 0;
2941 : 39082120 : op_alt[i].constraint = p;
2942 : 39082120 : op_alt[i].matches = -1;
2943 : 39082120 : op_alt[i].matched = -1;
2944 : :
2945 : 39082120 : if (*p == '\0' || *p == ',')
2946 : : {
2947 : 1685593 : op_alt[i].anything_ok = 1;
2948 : 1685593 : continue;
2949 : : }
2950 : :
2951 : 99376459 : for (;;)
2952 : : {
2953 : 99376459 : char c = *p;
2954 : 99376459 : if (c == '#')
2955 : 0 : do
2956 : 0 : c = *++p;
2957 : 0 : while (c != ',' && c != '\0');
2958 : 99376459 : if (c == ',' || c == '\0')
2959 : : {
2960 : 37396527 : p++;
2961 : 37396527 : break;
2962 : : }
2963 : :
2964 : 61979932 : switch (c)
2965 : : {
2966 : 5644266 : case '?':
2967 : 5644266 : op_alt[i].reject += 6;
2968 : 5644266 : break;
2969 : 394616 : case '!':
2970 : 394616 : op_alt[i].reject += 600;
2971 : 394616 : break;
2972 : 56236 : case '&':
2973 : 56236 : op_alt[i].earlyclobber = 1;
2974 : 56236 : break;
2975 : :
2976 : 2003485 : case '0': case '1': case '2': case '3': case '4':
2977 : 2003485 : case '5': case '6': case '7': case '8': case '9':
2978 : 2003485 : {
2979 : 2003485 : char *end;
2980 : 2003485 : op_alt[i].matches = strtoul (p, &end, 10);
2981 : 2003485 : op_alt[op_alt[i].matches].matched = i;
2982 : 2003485 : p = end;
2983 : : }
2984 : 2003485 : continue;
2985 : :
2986 : 30642 : case 'X':
2987 : 30642 : op_alt[i].anything_ok = 1;
2988 : 30642 : break;
2989 : :
2990 : 202411 : case 'g':
2991 : 202411 : op_alt[i].cl =
2992 : 202411 : reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
2993 : 202411 : break;
2994 : :
2995 : 53648276 : default:
2996 : 53648276 : enum constraint_num cn = lookup_constraint (p);
2997 : 53648276 : enum reg_class cl;
2998 : 53648276 : switch (get_constraint_type (cn))
2999 : : {
3000 : 38281728 : case CT_REGISTER:
3001 : 38281728 : cl = reg_class_for_constraint (cn);
3002 : 27554290 : if (cl != NO_REGS)
3003 : : {
3004 : 24027534 : op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
3005 : 24027534 : auto filter_id = get_register_filter_id (cn);
3006 : 24027534 : if (filter_id >= 0)
3007 : : op_alt[i].register_filters |= 1U << filter_id;
3008 : : }
3009 : : break;
3010 : :
3011 : : case CT_CONST_INT:
3012 : : break;
3013 : :
3014 : 7745192 : case CT_MEMORY:
3015 : 7745192 : case CT_SPECIAL_MEMORY:
3016 : 7745192 : case CT_RELAXED_MEMORY:
3017 : 7745192 : op_alt[i].memory_ok = 1;
3018 : 7745192 : break;
3019 : :
3020 : 86257 : case CT_ADDRESS:
3021 : 86257 : if (oploc && !address_operand (*oploc[i], VOIDmode))
3022 : : break;
3023 : :
3024 : 86238 : op_alt[i].is_address = 1;
3025 : 86238 : op_alt[i].cl
3026 : 86238 : = (reg_class_subunion
3027 : 86238 : [(int) op_alt[i].cl]
3028 : 86238 : [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
3029 : 86238 : ADDRESS, SCRATCH)]);
3030 : 86238 : break;
3031 : :
3032 : : case CT_FIXED_FORM:
3033 : : break;
3034 : : }
3035 : : break;
3036 : 2003485 : }
3037 : 59976447 : p += CONSTRAINT_LEN (c, p);
3038 : : }
3039 : : }
3040 : : }
3041 : 4697212 : }
3042 : :
3043 : : /* Return an array of operand_alternative instructions for
3044 : : instruction ICODE. */
3045 : :
3046 : : const operand_alternative *
3047 : 293183177 : preprocess_insn_constraints (unsigned int icode)
3048 : : {
3049 : 293183177 : gcc_checking_assert (IN_RANGE (icode, 0, NUM_INSN_CODES - 1));
3050 : 293183177 : if (this_target_recog->x_op_alt[icode])
3051 : : return this_target_recog->x_op_alt[icode];
3052 : :
3053 : 5416309 : int n_operands = insn_data[icode].n_operands;
3054 : 5416309 : if (n_operands == 0)
3055 : : return 0;
3056 : : /* Always provide at least one alternative so that which_op_alt ()
3057 : : works correctly. If the instruction has 0 alternatives (i.e. all
3058 : : constraint strings are empty) then each operand in this alternative
3059 : : will have anything_ok set. */
3060 : 2905428 : int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
3061 : 2905428 : int n_entries = n_operands * n_alternatives;
3062 : :
3063 : 2905428 : operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
3064 : 2905428 : const char **constraints = XALLOCAVEC (const char *, n_operands);
3065 : :
3066 : 9855366 : for (int i = 0; i < n_operands; ++i)
3067 : 6949938 : constraints[i] = insn_data[icode].operand[i].constraint;
3068 : 2905428 : preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
3069 : : NULL);
3070 : :
3071 : 2905428 : this_target_recog->x_op_alt[icode] = op_alt;
3072 : 2905428 : return op_alt;
3073 : : }
3074 : :
3075 : : /* After calling extract_insn, you can use this function to extract some
3076 : : information from the constraint strings into a more usable form.
3077 : : The collected data is stored in recog_op_alt. */
3078 : :
3079 : : void
3080 : 199742844 : preprocess_constraints (rtx_insn *insn)
3081 : : {
3082 : 199742844 : int icode = INSN_CODE (insn);
3083 : 199742844 : if (icode >= 0)
3084 : 197991395 : recog_op_alt = preprocess_insn_constraints (icode);
3085 : : else
3086 : : {
3087 : 1751449 : int n_operands = recog_data.n_operands;
3088 : 1751449 : int n_alternatives = recog_data.n_alternatives;
3089 : 1751449 : int n_entries = n_operands * n_alternatives;
3090 : 1751449 : memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
3091 : 1751449 : preprocess_constraints (n_operands, n_alternatives,
3092 : : recog_data.constraints, asm_op_alt,
3093 : : NULL);
3094 : 1751449 : recog_op_alt = asm_op_alt;
3095 : : }
3096 : 199742844 : }
3097 : :
3098 : : /* Check the operands of an insn against the insn's operand constraints
3099 : : and return 1 if they match any of the alternatives in ALTERNATIVES.
3100 : :
3101 : : The information about the insn's operands, constraints, operand modes
3102 : : etc. is obtained from the global variables set up by extract_insn.
3103 : :
3104 : : WHICH_ALTERNATIVE is set to a number which indicates which
3105 : : alternative of constraints was matched: 0 for the first alternative,
3106 : : 1 for the next, etc.
3107 : :
3108 : : In addition, when two operands are required to match
3109 : : and it happens that the output operand is (reg) while the
3110 : : input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
3111 : : make the output operand look like the input.
3112 : : This is because the output operand is the one the template will print.
3113 : :
3114 : : This is used in final, just before printing the assembler code and by
3115 : : the routines that determine an insn's attribute.
3116 : :
3117 : : If STRICT is a positive nonzero value, it means that we have been
3118 : : called after reload has been completed. In that case, we must
3119 : : do all checks strictly. If it is zero, it means that we have been called
3120 : : before reload has completed. In that case, we first try to see if we can
3121 : : find an alternative that matches strictly. If not, we try again, this
3122 : : time assuming that reload will fix up the insn. This provides a "best
3123 : : guess" for the alternative and is used to compute attributes of insns prior
3124 : : to reload. A negative value of STRICT is used for this internal call. */
3125 : :
3126 : : struct funny_match
3127 : : {
3128 : : int this_op, other;
3129 : : };
3130 : :
3131 : : bool
3132 : 1131294472 : constrain_operands (int strict, alternative_mask alternatives)
3133 : : {
3134 : 1132234300 : const char *constraints[MAX_RECOG_OPERANDS];
3135 : 1132234300 : int matching_operands[MAX_RECOG_OPERANDS];
3136 : 1132234300 : int earlyclobber[MAX_RECOG_OPERANDS];
3137 : 1132234300 : int c;
3138 : :
3139 : 1132234300 : struct funny_match funny_match[MAX_RECOG_OPERANDS];
3140 : 1132234300 : int funny_match_index;
3141 : :
3142 : 1132234300 : which_alternative = 0;
3143 : 1132234300 : if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0)
3144 : : return true;
3145 : :
3146 : 3360137043 : for (c = 0; c < recog_data.n_operands; c++)
3147 : 2288335642 : constraints[c] = recog_data.constraints[c];
3148 : :
3149 : 4016888459 : do
3150 : : {
3151 : 4016888459 : int seen_earlyclobber_at = -1;
3152 : 4016888459 : int opno;
3153 : 4016888459 : bool lose = false;
3154 : 4016888459 : funny_match_index = 0;
3155 : :
3156 : 4016888459 : if (!TEST_BIT (alternatives, which_alternative))
3157 : : {
3158 : : int i;
3159 : :
3160 : 2717886123 : for (i = 0; i < recog_data.n_operands; i++)
3161 : 3646949232 : constraints[i] = skip_alternative (constraints[i]);
3162 : :
3163 : 894411507 : which_alternative++;
3164 : 894411507 : continue;
3165 : 894411507 : }
3166 : :
3167 : 9597503983 : for (opno = 0; opno < recog_data.n_operands; opno++)
3168 : 6475027031 : matching_operands[opno] = -1;
3169 : :
3170 : 9597503983 : for (opno = 0; opno < recog_data.n_operands; opno++)
3171 : : {
3172 : 6475027031 : rtx op = recog_data.operand[opno];
3173 : 6475027031 : machine_mode mode = GET_MODE (op);
3174 : 6475027031 : const char *p = constraints[opno];
3175 : 6475027031 : int offset = 0;
3176 : 6475027031 : bool win = false;
3177 : 6475027031 : int val;
3178 : 6475027031 : int len;
3179 : :
3180 : 6475027031 : earlyclobber[opno] = 0;
3181 : :
3182 : 6475027031 : if (GET_CODE (op) == SUBREG)
3183 : : {
3184 : 1567625 : if (REG_P (SUBREG_REG (op))
3185 : 1567625 : && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
3186 : 428 : offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
3187 : 428 : GET_MODE (SUBREG_REG (op)),
3188 : 428 : SUBREG_BYTE (op),
3189 : : GET_MODE (op));
3190 : 1567625 : op = SUBREG_REG (op);
3191 : : }
3192 : :
3193 : : /* An empty constraint or empty alternative
3194 : : allows anything which matched the pattern. */
3195 : 6475027031 : if (*p == 0 || *p == ',')
3196 : 94951298 : win = true;
3197 : :
3198 : 16355817927 : do
3199 : 16355817927 : switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
3200 : : {
3201 : : case '\0':
3202 : : len = 0;
3203 : : break;
3204 : 6130731609 : case ',':
3205 : 6130731609 : c = '\0';
3206 : 6130731609 : break;
3207 : 20 : case '-':
3208 : 20 : raw_constraint_p = true;
3209 : 20 : break;
3210 : :
3211 : 0 : case '#':
3212 : : /* Ignore rest of this alternative as far as
3213 : : constraint checking is concerned. */
3214 : 0 : do
3215 : 0 : p++;
3216 : 0 : while (*p && *p != ',');
3217 : : len = 0;
3218 : : break;
3219 : :
3220 : 420452 : case '&':
3221 : 420452 : earlyclobber[opno] = 1;
3222 : 420452 : if (seen_earlyclobber_at < 0)
3223 : 402306 : seen_earlyclobber_at = opno;
3224 : : break;
3225 : :
3226 : 186673617 : case '0': case '1': case '2': case '3': case '4':
3227 : 186673617 : case '5': case '6': case '7': case '8': case '9':
3228 : 186673617 : {
3229 : : /* This operand must be the same as a previous one.
3230 : : This kind of constraint is used for instructions such
3231 : : as add when they take only two operands.
3232 : :
3233 : : Note that the lower-numbered operand is passed first.
3234 : :
3235 : : If we are not testing strictly, assume that this
3236 : : constraint will be satisfied. */
3237 : :
3238 : 186673617 : char *end;
3239 : 186673617 : int match;
3240 : :
3241 : 186673617 : match = strtoul (p, &end, 10);
3242 : 186673617 : p = end;
3243 : :
3244 : 186673617 : if (strict < 0)
3245 : : val = 1;
3246 : : else
3247 : : {
3248 : 185712236 : rtx op1 = recog_data.operand[match];
3249 : 185712236 : rtx op2 = recog_data.operand[opno];
3250 : 185712236 : val = operands_match_p (op1, op2);
3251 : : }
3252 : :
3253 : 186673617 : matching_operands[opno] = match;
3254 : 186673617 : matching_operands[match] = opno;
3255 : :
3256 : 186673617 : if (val != 0)
3257 : 153305568 : win = true;
3258 : :
3259 : : /* If output is *x and input is *--x, arrange later
3260 : : to change the output to *--x as well, since the
3261 : : output op is the one that will be printed. */
3262 : 186673617 : if (val == 2 && strict > 0)
3263 : : {
3264 : 0 : funny_match[funny_match_index].this_op = opno;
3265 : 0 : funny_match[funny_match_index++].other = match;
3266 : : }
3267 : : }
3268 : 186673617 : len = 0;
3269 : 186673617 : break;
3270 : :
3271 : 261554 : case 'p':
3272 : : /* p is used for address_operands. When we are called by
3273 : : gen_reload, no one will have checked that the address is
3274 : : strictly valid, i.e., that all pseudos requiring hard regs
3275 : : have gotten them. We also want to make sure we have a
3276 : : valid mode. */
3277 : 261554 : {
3278 : 261467 : auto mem_mode = (recog_data.is_asm
3279 : 261554 : ? VOIDmode
3280 : : : recog_data.operand_mode[opno]);
3281 : 261554 : if ((GET_MODE (op) == VOIDmode
3282 : 261554 : || SCALAR_INT_MODE_P (GET_MODE (op)))
3283 : 523082 : && (strict <= 0
3284 : 261554 : || strict_memory_address_p (mem_mode, op)))
3285 : 261488 : win = true;
3286 : : break;
3287 : : }
3288 : :
3289 : : /* No need to check general_operand again;
3290 : : it was done in insn-recog.cc. Well, except that reload
3291 : : doesn't check the validity of its replacements, but
3292 : : that should only matter when there's a bug. */
3293 : 125896832 : case 'g':
3294 : : /* Anything goes unless it is a REG and really has a hard reg
3295 : : but the hard reg is not in the class GENERAL_REGS. */
3296 : 125896832 : if (REG_P (op))
3297 : : {
3298 : 47476323 : if (strict < 0
3299 : : || GENERAL_REGS == ALL_REGS
3300 : 47476271 : || (reload_in_progress
3301 : 0 : && REGNO (op) >= FIRST_PSEUDO_REGISTER)
3302 : 94952594 : || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
3303 : : win = true;
3304 : : }
3305 : 78420509 : else if (strict < 0 || general_operand (op, mode))
3306 : : win = true;
3307 : : break;
3308 : :
3309 : 249 : case '{':
3310 : 240 : if ((REG_P (op) && HARD_REGISTER_P (op)
3311 : 240 : && (int) REGNO (op) == decode_hard_reg_constraint (p))
3312 : 261 : || !reload_completed)
3313 : : win = true;
3314 : : break;
3315 : :
3316 : 9567538172 : default:
3317 : 9567538172 : {
3318 : 9567538172 : enum constraint_num cn = lookup_constraint (p);
3319 : 9567538172 : enum reg_class cl = reg_class_for_constraint (cn);
3320 : 4434896616 : if (cl != NO_REGS)
3321 : : {
3322 : 4258795426 : auto *filter = get_register_filter (cn);
3323 : 4258795426 : if (strict < 0
3324 : 4257040251 : || (strict == 0
3325 : 23080399 : && REG_P (op)
3326 : 17007522 : && REGNO (op) >= FIRST_PSEUDO_REGISTER)
3327 : 6150932 : || (strict == 0 && GET_CODE (op) == SCRATCH)
3328 : 8498890025 : || (REG_P (op)
3329 : 3039346914 : && reg_fits_class_p (op, cl, offset, mode)
3330 : : && (!filter
3331 : : || TEST_HARD_REG_BIT (*filter,
3332 : : REGNO (op) + offset))))
3333 : : win = true;
3334 : : }
3335 : :
3336 : 5308742746 : else if (constraint_satisfied_p (op, cn))
3337 : : win = true;
3338 : :
3339 : 4425469558 : else if ((insn_extra_memory_constraint (cn)
3340 : : || insn_extra_relaxed_memory_constraint (cn))
3341 : : /* Every memory operand can be reloaded to fit. */
3342 : 4425469558 : && ((strict < 0 && MEM_P (op))
3343 : : /* Before reload, accept what reload can turn
3344 : : into a mem. */
3345 : 708791 : || (strict < 0 && CONSTANT_P (op))
3346 : : /* Before reload, accept a pseudo or hard register,
3347 : : since LRA can turn it into a mem. */
3348 : 708427 : || (strict < 0 && targetm.lra_p () && REG_P (op))
3349 : : /* During reload, accept a pseudo */
3350 : 928158431 : || (reload_in_progress && REG_P (op)
3351 : 0 : && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
3352 : : win = true;
3353 : 4424760767 : else if (insn_extra_address_constraint (cn)
3354 : : /* Every address operand can be reloaded to fit. */
3355 : 4424760767 : && strict < 0)
3356 : : win = true;
3357 : : /* Cater to architectures like IA-64 that define extra memory
3358 : : constraints without using define_memory_constraint. */
3359 : 4424760767 : else if (reload_in_progress
3360 : 0 : && REG_P (op)
3361 : 0 : && REGNO (op) >= FIRST_PSEUDO_REGISTER
3362 : 0 : && reg_renumber[REGNO (op)] < 0
3363 : 0 : && reg_equiv_mem (REGNO (op)) != 0
3364 : 4424760767 : && constraint_satisfied_p
3365 : 0 : (reg_equiv_mem (REGNO (op)), cn))
3366 : : win = true;
3367 : : break;
3368 : : }
3369 : : }
3370 : 16355817927 : while (p += len, c);
3371 : :
3372 : 6475027031 : raw_constraint_p = false;
3373 : 6475027031 : constraints[opno] = p;
3374 : : /* If this operand did not win somehow,
3375 : : this alternative loses. */
3376 : 6475027031 : if (! win)
3377 : 3125923377 : lose = true;
3378 : : }
3379 : : /* This alternative won; the operands are ok.
3380 : : Change whichever operands this alternative says to change. */
3381 : 3122476952 : if (! lose)
3382 : : {
3383 : 1067559101 : int opno, eopno;
3384 : :
3385 : : /* See if any earlyclobber operand conflicts with some other
3386 : : operand. */
3387 : :
3388 : 1067559101 : if (strict > 0 && seen_earlyclobber_at >= 0)
3389 : 1019395 : for (eopno = seen_earlyclobber_at;
3390 : 1344881 : eopno < recog_data.n_operands;
3391 : : eopno++)
3392 : : /* Ignore earlyclobber operands now in memory,
3393 : : because we would often report failure when we have
3394 : : two memory operands, one of which was formerly a REG. */
3395 : 1019395 : if (earlyclobber[eopno]
3396 : 341804 : && REG_P (recog_data.operand[eopno]))
3397 : 1735046 : for (opno = 0; opno < recog_data.n_operands; opno++)
3398 : 1393242 : if ((MEM_P (recog_data.operand[opno])
3399 : 1255477 : || recog_data.operand_type[opno] != OP_OUT)
3400 : 830952 : && opno != eopno
3401 : : /* Ignore things like match_operator operands. */
3402 : 830305 : && *recog_data.constraints[opno] != 0
3403 : 864871 : && ! (matching_operands[opno] == eopno
3404 : 104462 : && operands_match_p (recog_data.operand[opno],
3405 : : recog_data.operand[eopno]))
3406 : 2051308 : && ! safe_from_earlyclobber (recog_data.operand[opno],
3407 : : recog_data.operand[eopno]))
3408 : : lose = true;
3409 : :
3410 : 1067559101 : if (! lose)
3411 : : {
3412 : 1067558068 : while (--funny_match_index >= 0)
3413 : : {
3414 : 0 : recog_data.operand[funny_match[funny_match_index].other]
3415 : 0 : = recog_data.operand[funny_match[funny_match_index].this_op];
3416 : : }
3417 : :
3418 : : /* For operands without < or > constraints reject side-effects. */
3419 : : if (AUTO_INC_DEC && recog_data.is_asm)
3420 : : {
3421 : : for (opno = 0; opno < recog_data.n_operands; opno++)
3422 : : if (MEM_P (recog_data.operand[opno]))
3423 : : switch (GET_CODE (XEXP (recog_data.operand[opno], 0)))
3424 : : {
3425 : : case PRE_INC:
3426 : : case POST_INC:
3427 : : case PRE_DEC:
3428 : : case POST_DEC:
3429 : : case PRE_MODIFY:
3430 : : case POST_MODIFY:
3431 : : if (strchr (recog_data.constraints[opno], '<') == NULL
3432 : : && strchr (recog_data.constraints[opno], '>')
3433 : : == NULL)
3434 : : return false;
3435 : : break;
3436 : : default:
3437 : : break;
3438 : : }
3439 : : }
3440 : :
3441 : : return true;
3442 : : }
3443 : : }
3444 : :
3445 : 2054918884 : which_alternative++;
3446 : : }
3447 : 2949330391 : while (which_alternative < recog_data.n_alternatives);
3448 : :
3449 : 4243333 : which_alternative = -1;
3450 : : /* If we are about to reject this, but we are not to test strictly,
3451 : : try a very loose test. Only return failure if it fails also. */
3452 : 4243333 : if (strict == 0)
3453 : : return constrain_operands (-1, alternatives);
3454 : : else
3455 : : return false;
3456 : : }
3457 : :
3458 : : /* Return true iff OPERAND (assumed to be a REG rtx)
3459 : : is a hard reg in class CLASS when its regno is offset by OFFSET
3460 : : and changed to mode MODE.
3461 : : If REG occupies multiple hard regs, all of them must be in CLASS. */
3462 : :
3463 : : bool
3464 : 3334141517 : reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
3465 : : machine_mode mode)
3466 : : {
3467 : 3334141517 : unsigned int regno = REGNO (operand);
3468 : :
3469 : 3334141517 : if (cl == NO_REGS)
3470 : : return false;
3471 : :
3472 : : /* Regno must not be a pseudo register. Offset may be negative. */
3473 : 3237053245 : return (HARD_REGISTER_NUM_P (regno)
3474 : 3236973993 : && HARD_REGISTER_NUM_P (regno + offset)
3475 : 6474027238 : && in_hard_reg_set_p (reg_class_contents[(int) cl], mode,
3476 : : regno + offset));
3477 : : }
3478 : :
3479 : : /* Split single instruction. Helper function for split_all_insns and
3480 : : split_all_insns_noflow. Return last insn in the sequence if successful,
3481 : : or NULL if unsuccessful. */
3482 : :
3483 : : static rtx_insn *
3484 : 381643391 : split_insn (rtx_insn *insn)
3485 : : {
3486 : : /* Split insns here to get max fine-grain parallelism. */
3487 : 381643391 : rtx_insn *first = PREV_INSN (insn);
3488 : 381643391 : rtx_insn *last = try_split (PATTERN (insn), insn, 1);
3489 : 381643391 : rtx insn_set, last_set, note;
3490 : :
3491 : 381643391 : if (last == insn)
3492 : : return NULL;
3493 : :
3494 : : /* If the original instruction was a single set that was known to be
3495 : : equivalent to a constant, see if we can say the same about the last
3496 : : instruction in the split sequence. The two instructions must set
3497 : : the same destination. */
3498 : 6217213 : insn_set = single_set (insn);
3499 : 6217213 : if (insn_set)
3500 : : {
3501 : 6127516 : last_set = single_set (last);
3502 : 6127516 : if (last_set && rtx_equal_p (SET_DEST (last_set), SET_DEST (insn_set)))
3503 : : {
3504 : 2881675 : note = find_reg_equal_equiv_note (insn);
3505 : 2881675 : if (note && CONSTANT_P (XEXP (note, 0)))
3506 : 83077 : set_unique_reg_note (last, REG_EQUAL, XEXP (note, 0));
3507 : 2798598 : else if (CONSTANT_P (SET_SRC (insn_set)))
3508 : 34836 : set_unique_reg_note (last, REG_EQUAL,
3509 : : copy_rtx (SET_SRC (insn_set)));
3510 : : }
3511 : : }
3512 : :
3513 : : /* try_split returns the NOTE that INSN became. */
3514 : 6217213 : SET_INSN_DELETED (insn);
3515 : :
3516 : : /* ??? Coddle to md files that generate subregs in post-reload
3517 : : splitters instead of computing the proper hard register. */
3518 : 6217213 : if (reload_completed && first != last)
3519 : : {
3520 : 5791861 : first = NEXT_INSN (first);
3521 : 2694609 : for (;;)
3522 : : {
3523 : 8486470 : if (INSN_P (first))
3524 : 8482106 : cleanup_subreg_operands (first);
3525 : 8486470 : if (first == last)
3526 : : break;
3527 : 2694609 : first = NEXT_INSN (first);
3528 : : }
3529 : : }
3530 : :
3531 : : return last;
3532 : : }
3533 : :
3534 : : /* Split all insns in the function. If UPD_LIFE, update life info after. */
3535 : :
3536 : : void
3537 : 4007726 : split_all_insns (void)
3538 : : {
3539 : 4007726 : bool changed;
3540 : 4007726 : bool need_cfg_cleanup = false;
3541 : 4007726 : basic_block bb;
3542 : :
3543 : 4007726 : auto_sbitmap blocks (last_basic_block_for_fn (cfun));
3544 : 4007726 : bitmap_clear (blocks);
3545 : 4007726 : changed = false;
3546 : :
3547 : 44026520 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
3548 : : {
3549 : 40018794 : rtx_insn *insn, *next;
3550 : 40018794 : bool finish = false;
3551 : :
3552 : 40018794 : rtl_profile_for_bb (bb);
3553 : 503173434 : for (insn = BB_HEAD (bb); !finish ; insn = next)
3554 : : {
3555 : : /* Can't use `next_real_insn' because that might go across
3556 : : CODE_LABELS and short-out basic blocks. */
3557 : 463154640 : next = NEXT_INSN (insn);
3558 : 463154640 : finish = (insn == BB_END (bb));
3559 : :
3560 : : /* If INSN has a REG_EH_REGION note and we split INSN, the
3561 : : resulting split may not have/need REG_EH_REGION notes.
3562 : :
3563 : : If that happens and INSN was the last reference to the
3564 : : given EH region, then the EH region will become unreachable.
3565 : : We cannot leave the unreachable blocks in the CFG as that
3566 : : will trigger a checking failure.
3567 : :
3568 : : So track if INSN has a REG_EH_REGION note. If so and we
3569 : : split INSN, then trigger a CFG cleanup. */
3570 : 463154640 : rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3571 : 463154640 : if (INSN_P (insn))
3572 : : {
3573 : 381690170 : rtx set = single_set (insn);
3574 : :
3575 : : /* Don't split no-op move insns. These should silently
3576 : : disappear later in final. Splitting such insns would
3577 : : break the code that handles LIBCALL blocks. */
3578 : 381690170 : if (set && set_noop_p (set))
3579 : : {
3580 : : /* Nops get in the way while scheduling, so delete them
3581 : : now if register allocation has already been done. It
3582 : : is too risky to try to do this before register
3583 : : allocation, and there are unlikely to be very many
3584 : : nops then anyways. */
3585 : 46779 : if (reload_completed)
3586 : 46750 : delete_insn_and_edges (insn);
3587 : 46779 : if (note)
3588 : 463154640 : need_cfg_cleanup = true;
3589 : : }
3590 : : else
3591 : : {
3592 : 381643391 : if (split_insn (insn))
3593 : : {
3594 : 6217213 : bitmap_set_bit (blocks, bb->index);
3595 : 6217213 : changed = true;
3596 : 6217213 : if (note)
3597 : 2904 : need_cfg_cleanup = true;
3598 : : }
3599 : : }
3600 : : }
3601 : : }
3602 : : }
3603 : :
3604 : 4007726 : default_rtl_profile ();
3605 : 4007726 : if (changed)
3606 : : {
3607 : 754241 : find_many_sub_basic_blocks (blocks);
3608 : :
3609 : : /* Splitting could drop an REG_EH_REGION if it potentially
3610 : : trapped in its original form, but does not in its split
3611 : : form. Consider a FLOAT_TRUNCATE which splits into a memory
3612 : : store/load pair and -fnon-call-exceptions. */
3613 : 754241 : if (need_cfg_cleanup)
3614 : 1366 : cleanup_cfg (0);
3615 : : }
3616 : :
3617 : 4007726 : checking_verify_flow_info ();
3618 : 4007726 : }
3619 : :
3620 : : /* Same as split_all_insns, but do not expect CFG to be available.
3621 : : Used by machine dependent reorg passes. */
3622 : :
3623 : : void
3624 : 0 : split_all_insns_noflow (void)
3625 : : {
3626 : 0 : rtx_insn *next, *insn;
3627 : :
3628 : 0 : for (insn = get_insns (); insn; insn = next)
3629 : : {
3630 : 0 : next = NEXT_INSN (insn);
3631 : 0 : if (INSN_P (insn))
3632 : : {
3633 : : /* Don't split no-op move insns. These should silently
3634 : : disappear later in final. Splitting such insns would
3635 : : break the code that handles LIBCALL blocks. */
3636 : 0 : rtx set = single_set (insn);
3637 : 0 : if (set && set_noop_p (set))
3638 : : {
3639 : : /* Nops get in the way while scheduling, so delete them
3640 : : now if register allocation has already been done. It
3641 : : is too risky to try to do this before register
3642 : : allocation, and there are unlikely to be very many
3643 : : nops then anyways.
3644 : :
3645 : : ??? Should we use delete_insn when the CFG isn't valid? */
3646 : 0 : if (reload_completed)
3647 : 0 : delete_insn_and_edges (insn);
3648 : : }
3649 : : else
3650 : 0 : split_insn (insn);
3651 : : }
3652 : : }
3653 : 0 : }
3654 : :
3655 : : struct peep2_insn_data
3656 : : {
3657 : : rtx_insn *insn;
3658 : : regset live_before;
3659 : : };
3660 : :
3661 : : static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
3662 : : static int peep2_current;
3663 : :
3664 : : static bool peep2_do_rebuild_jump_labels;
3665 : : static bool peep2_do_cleanup_cfg;
3666 : :
3667 : : /* The number of instructions available to match a peep2. */
3668 : : int peep2_current_count;
3669 : :
3670 : : /* A marker indicating the last insn of the block. The live_before regset
3671 : : for this element is correct, indicating DF_LIVE_OUT for the block. */
3672 : : #define PEEP2_EOB invalid_insn_rtx
3673 : :
3674 : : /* Wrap N to fit into the peep2_insn_data buffer. */
3675 : :
3676 : : static int
3677 : 428421164 : peep2_buf_position (int n)
3678 : : {
3679 : 0 : if (n >= MAX_INSNS_PER_PEEP2 + 1)
3680 : 144552514 : n -= MAX_INSNS_PER_PEEP2 + 1;
3681 : 428401102 : return n;
3682 : : }
3683 : :
3684 : : /* Return the Nth non-note insn after `current', or return NULL_RTX if it
3685 : : does not exist. Used by the recognizer to find the next insn to match
3686 : : in a multi-insn pattern. */
3687 : :
3688 : : rtx_insn *
3689 : 222100410 : peep2_next_insn (int n)
3690 : : {
3691 : 222100410 : gcc_assert (n <= peep2_current_count);
3692 : :
3693 : 222100410 : n = peep2_buf_position (peep2_current + n);
3694 : :
3695 : 222100410 : return peep2_insn_data[n].insn;
3696 : : }
3697 : :
3698 : : /* Return true if REGNO is dead before the Nth non-note insn
3699 : : after `current'. */
3700 : :
3701 : : bool
3702 : 13254110 : peep2_regno_dead_p (int ofs, int regno)
3703 : : {
3704 : 13254110 : gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
3705 : :
3706 : 13254110 : ofs = peep2_buf_position (peep2_current + ofs);
3707 : :
3708 : 13254110 : gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
3709 : :
3710 : 13254110 : return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno);
3711 : : }
3712 : :
3713 : : /* Similarly for a REG. */
3714 : :
3715 : : bool
3716 : 305204 : peep2_reg_dead_p (int ofs, rtx reg)
3717 : : {
3718 : 305204 : gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
3719 : :
3720 : 305204 : ofs = peep2_buf_position (peep2_current + ofs);
3721 : :
3722 : 305204 : gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
3723 : :
3724 : 305204 : unsigned int end_regno = END_REGNO (reg);
3725 : 381375 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
3726 : 305204 : if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno))
3727 : : return false;
3728 : : return true;
3729 : : }
3730 : :
3731 : : /* Regno offset to be used in the register search. */
3732 : : static int search_ofs;
3733 : :
3734 : : /* Try to find a hard register of mode MODE, matching the register class in
3735 : : CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
3736 : : remains available until the end of LAST_INSN. LAST_INSN may be NULL_RTX,
3737 : : in which case the only condition is that the register must be available
3738 : : before CURRENT_INSN.
3739 : : Registers that already have bits set in REG_SET will not be considered.
3740 : :
3741 : : If an appropriate register is available, it will be returned and the
3742 : : corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
3743 : : returned. */
3744 : :
3745 : : rtx
3746 : 601871 : peep2_find_free_register (int from, int to, const char *class_str,
3747 : : machine_mode mode, HARD_REG_SET *reg_set)
3748 : : {
3749 : 601871 : enum reg_class cl;
3750 : 601871 : HARD_REG_SET live;
3751 : 601871 : df_ref def;
3752 : 601871 : int i;
3753 : :
3754 : 601871 : gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
3755 : 601871 : gcc_assert (to < MAX_INSNS_PER_PEEP2 + 1);
3756 : :
3757 : 601871 : from = peep2_buf_position (peep2_current + from);
3758 : 601871 : to = peep2_buf_position (peep2_current + to);
3759 : :
3760 : 601871 : gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
3761 : 601871 : REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);
3762 : :
3763 : 601871 : while (from != to)
3764 : : {
3765 : 20062 : gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
3766 : :
3767 : : /* Don't use registers set or clobbered by the insn. */
3768 : 80248 : FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn)
3769 : 60186 : SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
3770 : :
3771 : 641995 : from = peep2_buf_position (from + 1);
3772 : : }
3773 : :
3774 : 601871 : cl = reg_class_for_constraint (lookup_constraint (class_str));
3775 : :
3776 : 5912345 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3777 : : {
3778 : 5907552 : int raw_regno, regno, j;
3779 : 5907552 : bool success;
3780 : :
3781 : : /* Distribute the free registers as much as possible. */
3782 : 5907552 : raw_regno = search_ofs + i;
3783 : 5907552 : if (raw_regno >= FIRST_PSEUDO_REGISTER)
3784 : 267972 : raw_regno -= FIRST_PSEUDO_REGISTER;
3785 : : #ifdef REG_ALLOC_ORDER
3786 : 5907552 : regno = reg_alloc_order[raw_regno];
3787 : : #else
3788 : : regno = raw_regno;
3789 : : #endif
3790 : :
3791 : : /* Can it support the mode we need? */
3792 : 5907552 : if (!targetm.hard_regno_mode_ok (regno, mode))
3793 : 1820800 : continue;
3794 : :
3795 : 4683830 : success = true;
3796 : 4683830 : for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
3797 : : {
3798 : : /* Don't allocate fixed registers. */
3799 : 4086752 : if (fixed_regs[regno + j])
3800 : : {
3801 : : success = false;
3802 : : break;
3803 : : }
3804 : : /* Don't allocate global registers. */
3805 : 2137395 : if (global_regs[regno + j])
3806 : : {
3807 : : success = false;
3808 : : break;
3809 : : }
3810 : : /* Make sure the register is of the right class. */
3811 : 2137395 : if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
3812 : : {
3813 : : success = false;
3814 : : break;
3815 : : }
3816 : : /* And that we don't create an extra save/restore. */
3817 : 1141254 : if (! crtl->abi->clobbers_full_reg_p (regno + j)
3818 : 1141254 : && ! df_regs_ever_live_p (regno + j))
3819 : : {
3820 : : success = false;
3821 : : break;
3822 : : }
3823 : :
3824 : 1104424 : if (! targetm.hard_regno_scratch_ok (regno + j))
3825 : : {
3826 : : success = false;
3827 : : break;
3828 : : }
3829 : :
3830 : : /* And we don't clobber traceback for noreturn functions. */
3831 : 1104296 : if ((regno + j == FRAME_POINTER_REGNUM
3832 : 1104296 : || regno + j == HARD_FRAME_POINTER_REGNUM)
3833 : 50475 : && (! reload_completed || frame_pointer_needed))
3834 : : {
3835 : : success = false;
3836 : : break;
3837 : : }
3838 : :
3839 : 1092593 : if (TEST_HARD_REG_BIT (*reg_set, regno + j)
3840 : 1092593 : || TEST_HARD_REG_BIT (live, regno + j))
3841 : : {
3842 : : success = false;
3843 : : break;
3844 : : }
3845 : : }
3846 : :
3847 : 4086752 : if (success)
3848 : : {
3849 : 597078 : add_to_hard_reg_set (reg_set, mode, regno);
3850 : :
3851 : : /* Start the next search with the next register. */
3852 : 597078 : if (++raw_regno >= FIRST_PSEUDO_REGISTER)
3853 : 6348 : raw_regno = 0;
3854 : 597078 : search_ofs = raw_regno;
3855 : :
3856 : 597078 : return gen_rtx_REG (mode, regno);
3857 : : }
3858 : : }
3859 : :
3860 : 4793 : search_ofs = 0;
3861 : 4793 : return NULL_RTX;
3862 : : }
3863 : :
3864 : : /* Forget all currently tracked instructions, only remember current
3865 : : LIVE regset. */
3866 : :
3867 : : static void
3868 : 10993441 : peep2_reinit_state (regset live)
3869 : : {
3870 : 10993441 : int i;
3871 : :
3872 : : /* Indicate that all slots except the last holds invalid data. */
3873 : 76954087 : for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
3874 : 65960646 : peep2_insn_data[i].insn = NULL;
3875 : 10993441 : peep2_current_count = 0;
3876 : :
3877 : : /* Indicate that the last slot contains live_after data. */
3878 : 10993441 : peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
3879 : 10993441 : peep2_current = MAX_INSNS_PER_PEEP2;
3880 : :
3881 : 10993441 : COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
3882 : 10993441 : }
3883 : :
3884 : : /* Copies frame related info of an insn (OLD_INSN) to the single
3885 : : insn (NEW_INSN) that was obtained by splitting OLD_INSN. */
3886 : :
3887 : : void
3888 : 134836 : copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
3889 : : {
3890 : 134836 : bool any_note = false;
3891 : 134836 : rtx note;
3892 : :
3893 : 134836 : if (!RTX_FRAME_RELATED_P (old_insn))
3894 : : return;
3895 : :
3896 : 134836 : RTX_FRAME_RELATED_P (new_insn) = 1;
3897 : :
3898 : : /* Allow the backend to fill in a note during the split. */
3899 : 134836 : for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
3900 : 0 : switch (REG_NOTE_KIND (note))
3901 : : {
3902 : 0 : case REG_FRAME_RELATED_EXPR:
3903 : 0 : case REG_CFA_DEF_CFA:
3904 : 0 : case REG_CFA_ADJUST_CFA:
3905 : 0 : case REG_CFA_OFFSET:
3906 : 0 : case REG_CFA_REGISTER:
3907 : 0 : case REG_CFA_EXPRESSION:
3908 : 0 : case REG_CFA_RESTORE:
3909 : 0 : case REG_CFA_SET_VDRAP:
3910 : 0 : any_note = true;
3911 : 0 : break;
3912 : : default:
3913 : : break;
3914 : : }
3915 : :
3916 : : /* If the backend didn't supply a note, copy one over. */
3917 : 134836 : if (!any_note)
3918 : 327355 : for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
3919 : 192519 : switch (REG_NOTE_KIND (note))
3920 : : {
3921 : 145939 : case REG_FRAME_RELATED_EXPR:
3922 : 145939 : case REG_CFA_DEF_CFA:
3923 : 145939 : case REG_CFA_ADJUST_CFA:
3924 : 145939 : case REG_CFA_OFFSET:
3925 : 145939 : case REG_CFA_REGISTER:
3926 : 145939 : case REG_CFA_EXPRESSION:
3927 : 145939 : case REG_CFA_RESTORE:
3928 : 145939 : case REG_CFA_SET_VDRAP:
3929 : 145939 : add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
3930 : 145939 : any_note = true;
3931 : 145939 : break;
3932 : : default:
3933 : : break;
3934 : : }
3935 : :
3936 : : /* If there still isn't a note, make sure the unwind info sees the
3937 : : same expression as before the split. */
3938 : 134836 : if (!any_note)
3939 : : {
3940 : 2162 : rtx old_set, new_set;
3941 : :
3942 : : /* The old insn had better have been simple, or annotated. */
3943 : 2162 : old_set = single_set (old_insn);
3944 : 2162 : gcc_assert (old_set != NULL);
3945 : :
3946 : 2162 : new_set = single_set (new_insn);
3947 : 2162 : if (!new_set || !rtx_equal_p (new_set, old_set))
3948 : 266 : add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
3949 : : }
3950 : :
3951 : : /* Copy prologue/epilogue status. This is required in order to keep
3952 : : proper placement of EPILOGUE_BEG and the DW_CFA_remember_state. */
3953 : 134836 : maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
3954 : : }
3955 : :
3956 : : /* While scanning basic block BB, we found a match of length MATCH_LEN + 1,
3957 : : starting at INSN. Perform the replacement, removing the old insns and
3958 : : replacing them with ATTEMPT. Returns the last insn emitted, or NULL
3959 : : if the replacement is rejected. */
3960 : :
3961 : : static rtx_insn *
3962 : 2293134 : peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
3963 : : {
3964 : 2293134 : int i;
3965 : 2293134 : rtx_insn *last, *before_try, *x;
3966 : 2293134 : rtx eh_note, as_note;
3967 : 2293134 : rtx_insn *old_insn;
3968 : 2293134 : rtx_insn *new_insn;
3969 : 2293134 : bool was_call = false;
3970 : :
3971 : : /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
3972 : : match more than one insn, or to be split into more than one insn. */
3973 : 2293134 : old_insn = peep2_insn_data[peep2_current].insn;
3974 : 2293134 : if (RTX_FRAME_RELATED_P (old_insn))
3975 : : {
3976 : 137609 : if (match_len != 0)
3977 : : return NULL;
3978 : :
3979 : : /* Look for one "active" insn. I.e. ignore any "clobber" insns that
3980 : : may be in the stream for the purpose of register allocation. */
3981 : 137609 : if (active_insn_p (attempt))
3982 : : new_insn = attempt;
3983 : : else
3984 : 34618 : new_insn = next_active_insn (attempt);
3985 : 137609 : if (next_active_insn (new_insn))
3986 : : return NULL;
3987 : :
3988 : : /* We have a 1-1 replacement. Copy over any frame-related info. */
3989 : 134819 : copy_frame_info_to_split_insn (old_insn, new_insn);
3990 : : }
3991 : :
3992 : : /* If we are splitting a CALL_INSN, look for the CALL_INSN
3993 : : in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
3994 : : cfg-related call notes. */
3995 : 4799356 : for (i = 0; i <= match_len; ++i)
3996 : : {
3997 : 2510506 : int j;
3998 : 2510506 : rtx note;
3999 : :
4000 : 2510506 : j = peep2_buf_position (peep2_current + i);
4001 : 2510506 : old_insn = peep2_insn_data[j].insn;
4002 : 2510506 : if (!CALL_P (old_insn))
4003 : 2509012 : continue;
4004 : 1494 : was_call = true;
4005 : :
4006 : : new_insn = attempt;
4007 : 1494 : while (new_insn != NULL_RTX)
4008 : : {
4009 : 1494 : if (CALL_P (new_insn))
4010 : : break;
4011 : 0 : new_insn = NEXT_INSN (new_insn);
4012 : : }
4013 : :
4014 : 1494 : gcc_assert (new_insn != NULL_RTX);
4015 : :
4016 : 1494 : CALL_INSN_FUNCTION_USAGE (new_insn)
4017 : 1494 : = CALL_INSN_FUNCTION_USAGE (old_insn);
4018 : 1494 : SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
4019 : :
4020 : 1494 : for (note = REG_NOTES (old_insn);
4021 : 6786 : note;
4022 : 5292 : note = XEXP (note, 1))
4023 : 5292 : switch (REG_NOTE_KIND (note))
4024 : : {
4025 : 0 : case REG_NORETURN:
4026 : 0 : case REG_SETJMP:
4027 : 0 : case REG_TM:
4028 : 0 : case REG_CALL_NOCF_CHECK:
4029 : 0 : add_reg_note (new_insn, REG_NOTE_KIND (note),
4030 : : XEXP (note, 0));
4031 : 0 : break;
4032 : : default:
4033 : : /* Discard all other reg notes. */
4034 : : break;
4035 : : }
4036 : :
4037 : : /* Croak if there is another call in the sequence. */
4038 : 1494 : while (++i <= match_len)
4039 : : {
4040 : 0 : j = peep2_buf_position (peep2_current + i);
4041 : 0 : old_insn = peep2_insn_data[j].insn;
4042 : 0 : gcc_assert (!CALL_P (old_insn));
4043 : : }
4044 : : break;
4045 : : }
4046 : :
4047 : : /* If we matched any instruction that had a REG_ARGS_SIZE, then
4048 : : move those notes over to the new sequence. */
4049 : 2290344 : as_note = NULL;
4050 : 4681725 : for (i = match_len; i >= 0; --i)
4051 : : {
4052 : 2510506 : int j = peep2_buf_position (peep2_current + i);
4053 : 2510506 : old_insn = peep2_insn_data[j].insn;
4054 : :
4055 : 2510506 : as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
4056 : 2510506 : if (as_note)
4057 : : break;
4058 : : }
4059 : :
4060 : 2290344 : i = peep2_buf_position (peep2_current + match_len);
4061 : 2290344 : eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
4062 : :
4063 : : /* Replace the old sequence with the new. */
4064 : 2290344 : rtx_insn *peepinsn = peep2_insn_data[i].insn;
4065 : 4580688 : last = emit_insn_after_setloc (attempt,
4066 : : peep2_insn_data[i].insn,
4067 : 2290344 : INSN_LOCATION (peepinsn));
4068 : 2290344 : if (JUMP_P (peepinsn) && JUMP_P (last))
4069 : 3266 : CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn);
4070 : 2290344 : before_try = PREV_INSN (insn);
4071 : 2290344 : delete_insn_chain (insn, peep2_insn_data[i].insn, false);
4072 : :
4073 : : /* Re-insert the EH_REGION notes. */
4074 : 2290344 : if (eh_note || (was_call && nonlocal_goto_handler_labels))
4075 : : {
4076 : 34 : edge eh_edge;
4077 : 34 : edge_iterator ei;
4078 : :
4079 : 39 : FOR_EACH_EDGE (eh_edge, ei, bb->succs)
4080 : 38 : if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
4081 : : break;
4082 : :
4083 : 34 : if (eh_note)
4084 : 34 : copy_reg_eh_region_note_backward (eh_note, last, before_try);
4085 : :
4086 : 34 : if (eh_edge)
4087 : 99 : for (x = last; x != before_try; x = PREV_INSN (x))
4088 : 66 : if (x != BB_END (bb)
4089 : 66 : && (can_throw_internal (x)
4090 : 33 : || can_nonlocal_goto (x)))
4091 : : {
4092 : 0 : edge nfte, nehe;
4093 : 0 : int flags;
4094 : :
4095 : 0 : nfte = split_block (bb, x);
4096 : 0 : flags = (eh_edge->flags
4097 : : & (EDGE_EH | EDGE_ABNORMAL));
4098 : 0 : if (CALL_P (x))
4099 : 0 : flags |= EDGE_ABNORMAL_CALL;
4100 : 0 : nehe = make_edge (nfte->src, eh_edge->dest,
4101 : : flags);
4102 : :
4103 : 0 : nehe->probability = eh_edge->probability;
4104 : 0 : nfte->probability = nehe->probability.invert ();
4105 : :
4106 : 0 : peep2_do_cleanup_cfg |= purge_dead_edges (nfte->dest);
4107 : 0 : bb = nfte->src;
4108 : 0 : eh_edge = nehe;
4109 : : }
4110 : :
4111 : : /* Converting possibly trapping insn to non-trapping is
4112 : : possible. Zap dummy outgoing edges. */
4113 : 34 : peep2_do_cleanup_cfg |= purge_dead_edges (bb);
4114 : : }
4115 : :
4116 : : /* Re-insert the ARGS_SIZE notes. */
4117 : 2290344 : if (as_note)
4118 : 119125 : fixup_args_size_notes (before_try, last, get_args_size (as_note));
4119 : :
4120 : : /* Scan the new insns for embedded side effects and add appropriate
4121 : : REG_INC notes. */
4122 : : if (AUTO_INC_DEC)
4123 : : for (x = last; x != before_try; x = PREV_INSN (x))
4124 : : if (NONDEBUG_INSN_P (x))
4125 : : add_auto_inc_notes (x, PATTERN (x));
4126 : :
4127 : : /* If we generated a jump instruction, it won't have
4128 : : JUMP_LABEL set. Recompute after we're done. */
4129 : 5324613 : for (x = last; x != before_try; x = PREV_INSN (x))
4130 : 3037535 : if (JUMP_P (x))
4131 : : {
4132 : 3266 : peep2_do_rebuild_jump_labels = true;
4133 : 3266 : break;
4134 : : }
4135 : :
4136 : : return last;
4137 : : }
4138 : :
4139 : : /* After performing a replacement in basic block BB, fix up the life
4140 : : information in our buffer. LAST is the last of the insns that we
4141 : : emitted as a replacement. PREV is the insn before the start of
4142 : : the replacement. MATCH_LEN + 1 is the number of instructions that were
4143 : : matched, and which now need to be replaced in the buffer. */
4144 : :
4145 : : static void
4146 : 2290344 : peep2_update_life (basic_block bb, int match_len, rtx_insn *last,
4147 : : rtx_insn *prev)
4148 : : {
4149 : 2290344 : int i = peep2_buf_position (peep2_current + match_len + 1);
4150 : 2290344 : rtx_insn *x;
4151 : 2290344 : regset_head live;
4152 : :
4153 : 2290344 : INIT_REG_SET (&live);
4154 : 2290344 : COPY_REG_SET (&live, peep2_insn_data[i].live_before);
4155 : :
4156 : 2290344 : gcc_assert (peep2_current_count >= match_len + 1);
4157 : 2290344 : peep2_current_count -= match_len + 1;
4158 : :
4159 : 2290344 : x = last;
4160 : 3040711 : do
4161 : : {
4162 : 3040711 : if (INSN_P (x))
4163 : : {
4164 : 3040711 : df_insn_rescan (x);
4165 : 3040711 : if (peep2_current_count < MAX_INSNS_PER_PEEP2)
4166 : : {
4167 : 2887066 : peep2_current_count++;
4168 : 2887066 : if (--i < 0)
4169 : 820609 : i = MAX_INSNS_PER_PEEP2;
4170 : 2887066 : peep2_insn_data[i].insn = x;
4171 : 2887066 : df_simulate_one_insn_backwards (bb, x, &live);
4172 : 2887066 : COPY_REG_SET (peep2_insn_data[i].live_before, &live);
4173 : : }
4174 : : }
4175 : 3040711 : x = PREV_INSN (x);
4176 : : }
4177 : 3040711 : while (x != prev);
4178 : 2290344 : CLEAR_REG_SET (&live);
4179 : :
4180 : 2290344 : peep2_current = i;
4181 : 2290344 : }
4182 : :
4183 : : /* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.
4184 : : Return true if we added it, false otherwise. The caller will try to match
4185 : : peepholes against the buffer if we return false; otherwise it will try to
4186 : : add more instructions to the buffer. */
4187 : :
4188 : : static bool
4189 : 82804523 : peep2_fill_buffer (basic_block bb, rtx_insn *insn, regset live)
4190 : : {
4191 : 82804523 : int pos;
4192 : :
4193 : : /* Once we have filled the maximum number of insns the buffer can hold,
4194 : : allow the caller to match the insns against peepholes. We wait until
4195 : : the buffer is full in case the target has similar peepholes of different
4196 : : length; we always want to match the longest if possible. */
4197 : 82804523 : if (peep2_current_count == MAX_INSNS_PER_PEEP2)
4198 : : return false;
4199 : :
4200 : : /* If an insn has RTX_FRAME_RELATED_P set, do not allow it to be matched with
4201 : : any other pattern, lest it change the semantics of the frame info. */
4202 : 63967949 : if (RTX_FRAME_RELATED_P (insn))
4203 : : {
4204 : : /* Let the buffer drain first. */
4205 : 7789201 : if (peep2_current_count > 0)
4206 : : return false;
4207 : : /* Now the insn will be the only thing in the buffer. */
4208 : : }
4209 : :
4210 : 59630824 : pos = peep2_buf_position (peep2_current + peep2_current_count);
4211 : 59630824 : peep2_insn_data[pos].insn = insn;
4212 : 59630824 : COPY_REG_SET (peep2_insn_data[pos].live_before, live);
4213 : 59630824 : peep2_current_count++;
4214 : :
4215 : 59630824 : df_simulate_one_insn_forwards (bb, insn, live);
4216 : 59630824 : return true;
4217 : : }
4218 : :
4219 : : /* Perform the peephole2 optimization pass. */
4220 : :
4221 : : static void
4222 : 966090 : peephole2_optimize (void)
4223 : : {
4224 : 966090 : rtx_insn *insn;
4225 : 966090 : bitmap live;
4226 : 966090 : int i;
4227 : 966090 : basic_block bb;
4228 : :
4229 : 966090 : peep2_do_cleanup_cfg = false;
4230 : 966090 : peep2_do_rebuild_jump_labels = false;
4231 : :
4232 : 966090 : df_set_flags (DF_LR_RUN_DCE);
4233 : 966090 : df_note_add_problem ();
4234 : 966090 : df_analyze ();
4235 : :
4236 : : /* Initialize the regsets we're going to use. */
4237 : 8694810 : for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
4238 : 6762630 : peep2_insn_data[i].live_before = BITMAP_ALLOC (®_obstack);
4239 : 966090 : search_ofs = 0;
4240 : 966090 : live = BITMAP_ALLOC (®_obstack);
4241 : :
4242 : 11959531 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
4243 : : {
4244 : 10993441 : bool past_end = false;
4245 : 10993441 : int pos;
4246 : :
4247 : 10993441 : rtl_profile_for_bb (bb);
4248 : :
4249 : : /* Start up propagation. */
4250 : 21986882 : bitmap_copy (live, DF_LR_IN (bb));
4251 : 10993441 : df_simulate_initialize_forwards (bb, live);
4252 : 10993441 : peep2_reinit_state (live);
4253 : :
4254 : 10993441 : insn = BB_HEAD (bb);
4255 : 206090830 : for (;;)
4256 : : {
4257 : 206090830 : rtx_insn *attempt, *head;
4258 : 206090830 : int match_len;
4259 : :
4260 : 206090830 : if (!past_end && !NONDEBUG_INSN_P (insn))
4261 : : {
4262 : 73168837 : next_insn:
4263 : 132799661 : insn = NEXT_INSN (insn);
4264 : 132799661 : if (insn == NEXT_INSN (BB_END (bb)))
4265 : 10993441 : past_end = true;
4266 : 135090005 : continue;
4267 : : }
4268 : 82804523 : if (!past_end && peep2_fill_buffer (bb, insn, live))
4269 : 59630824 : goto next_insn;
4270 : :
4271 : : /* If we did not fill an empty buffer, it signals the end of the
4272 : : block. */
4273 : 73291169 : if (peep2_current_count == 0)
4274 : : break;
4275 : :
4276 : : /* The buffer filled to the current maximum, so try to match. */
4277 : :
4278 : 62297728 : pos = peep2_buf_position (peep2_current + peep2_current_count);
4279 : 62297728 : peep2_insn_data[pos].insn = PEEP2_EOB;
4280 : 62297728 : COPY_REG_SET (peep2_insn_data[pos].live_before, live);
4281 : :
4282 : : /* Match the peephole. */
4283 : 62297728 : head = peep2_insn_data[peep2_current].insn;
4284 : 62297728 : attempt = peephole2_insns (PATTERN (head), head, &match_len);
4285 : 62297728 : if (attempt != NULL)
4286 : : {
4287 : 2293134 : rtx_insn *last = peep2_attempt (bb, head, match_len, attempt);
4288 : 2293134 : if (last)
4289 : : {
4290 : 2290344 : peep2_update_life (bb, match_len, last, PREV_INSN (attempt));
4291 : 2290344 : continue;
4292 : : }
4293 : : }
4294 : :
4295 : : /* No match: advance the buffer by one insn. */
4296 : 60007384 : peep2_current = peep2_buf_position (peep2_current + 1);
4297 : 60007384 : peep2_current_count--;
4298 : : }
4299 : : }
4300 : :
4301 : 966090 : default_rtl_profile ();
4302 : 8694810 : for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
4303 : 6762630 : BITMAP_FREE (peep2_insn_data[i].live_before);
4304 : 966090 : BITMAP_FREE (live);
4305 : 966090 : if (peep2_do_rebuild_jump_labels)
4306 : 2447 : rebuild_jump_labels (get_insns ());
4307 : 966090 : if (peep2_do_cleanup_cfg)
4308 : 0 : cleanup_cfg (CLEANUP_CFG_CHANGED);
4309 : 966090 : }
4310 : :
4311 : : /* Common predicates for use with define_bypass. */
4312 : :
4313 : : /* Helper function for store_data_bypass_p, handle just a single SET
4314 : : IN_SET. */
4315 : :
4316 : : static bool
4317 : 0 : store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
4318 : : {
4319 : 0 : if (!MEM_P (SET_DEST (in_set)))
4320 : : return false;
4321 : :
4322 : 0 : rtx out_set = single_set (out_insn);
4323 : 0 : if (out_set)
4324 : 0 : return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
4325 : :
4326 : 0 : rtx out_pat = PATTERN (out_insn);
4327 : 0 : if (GET_CODE (out_pat) != PARALLEL)
4328 : : return false;
4329 : :
4330 : 0 : for (int i = 0; i < XVECLEN (out_pat, 0); i++)
4331 : : {
4332 : 0 : rtx out_exp = XVECEXP (out_pat, 0, i);
4333 : :
4334 : 0 : if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
4335 : 0 : continue;
4336 : :
4337 : 0 : gcc_assert (GET_CODE (out_exp) == SET);
4338 : :
4339 : 0 : if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
4340 : : return false;
4341 : : }
4342 : :
4343 : : return true;
4344 : : }
4345 : :
4346 : : /* True if the dependency between OUT_INSN and IN_INSN is on the store
4347 : : data not the address operand(s) of the store. IN_INSN and OUT_INSN
4348 : : must be either a single_set or a PARALLEL with SETs inside. */
4349 : :
4350 : : bool
4351 : 0 : store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4352 : : {
4353 : 0 : rtx in_set = single_set (in_insn);
4354 : 0 : if (in_set)
4355 : 0 : return store_data_bypass_p_1 (out_insn, in_set);
4356 : :
4357 : 0 : rtx in_pat = PATTERN (in_insn);
4358 : 0 : if (GET_CODE (in_pat) != PARALLEL)
4359 : : return false;
4360 : :
4361 : 0 : for (int i = 0; i < XVECLEN (in_pat, 0); i++)
4362 : : {
4363 : 0 : rtx in_exp = XVECEXP (in_pat, 0, i);
4364 : :
4365 : 0 : if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
4366 : 0 : continue;
4367 : :
4368 : 0 : gcc_assert (GET_CODE (in_exp) == SET);
4369 : :
4370 : 0 : if (!store_data_bypass_p_1 (out_insn, in_exp))
4371 : : return false;
4372 : : }
4373 : :
4374 : : return true;
4375 : : }
4376 : :
4377 : : /* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
4378 : : condition, and not the THEN or ELSE branch. OUT_INSN may be either a single
4379 : : or multiple set; IN_INSN should be single_set for truth, but for convenience
4380 : : of insn categorization may be any JUMP or CALL insn. */
4381 : :
4382 : : bool
4383 : 0 : if_test_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4384 : : {
4385 : 0 : rtx out_set, in_set;
4386 : :
4387 : 0 : in_set = single_set (in_insn);
4388 : 0 : if (! in_set)
4389 : : {
4390 : 0 : gcc_assert (JUMP_P (in_insn) || CALL_P (in_insn));
4391 : : return false;
4392 : : }
4393 : :
4394 : 0 : if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
4395 : : return false;
4396 : 0 : in_set = SET_SRC (in_set);
4397 : :
4398 : 0 : out_set = single_set (out_insn);
4399 : 0 : if (out_set)
4400 : : {
4401 : 0 : if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
4402 : 0 : || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
4403 : 0 : return false;
4404 : : }
4405 : : else
4406 : : {
4407 : 0 : rtx out_pat;
4408 : 0 : int i;
4409 : :
4410 : 0 : out_pat = PATTERN (out_insn);
4411 : 0 : gcc_assert (GET_CODE (out_pat) == PARALLEL);
4412 : :
4413 : 0 : for (i = 0; i < XVECLEN (out_pat, 0); i++)
4414 : : {
4415 : 0 : rtx exp = XVECEXP (out_pat, 0, i);
4416 : :
4417 : 0 : if (GET_CODE (exp) == CLOBBER)
4418 : 0 : continue;
4419 : :
4420 : 0 : gcc_assert (GET_CODE (exp) == SET);
4421 : :
4422 : 0 : if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
4423 : 0 : || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
4424 : 0 : return false;
4425 : : }
4426 : : }
4427 : :
4428 : : return true;
4429 : : }
4430 : :
4431 : : static unsigned int
4432 : 966090 : rest_of_handle_peephole2 (void)
4433 : : {
4434 : 966090 : if (HAVE_peephole2)
4435 : 0 : peephole2_optimize ();
4436 : :
4437 : 966090 : return 0;
4438 : : }
4439 : :
4440 : : namespace {
4441 : :
4442 : : const pass_data pass_data_peephole2 =
4443 : : {
4444 : : RTL_PASS, /* type */
4445 : : "peephole2", /* name */
4446 : : OPTGROUP_NONE, /* optinfo_flags */
4447 : : TV_PEEPHOLE2, /* tv_id */
4448 : : 0, /* properties_required */
4449 : : 0, /* properties_provided */
4450 : : 0, /* properties_destroyed */
4451 : : 0, /* todo_flags_start */
4452 : : TODO_df_finish, /* todo_flags_finish */
4453 : : };
4454 : :
4455 : : class pass_peephole2 : public rtl_opt_pass
4456 : : {
4457 : : public:
4458 : 285689 : pass_peephole2 (gcc::context *ctxt)
4459 : 571378 : : rtl_opt_pass (pass_data_peephole2, ctxt)
4460 : : {}
4461 : :
4462 : : /* opt_pass methods: */
4463 : : /* The epiphany backend creates a second instance of this pass, so we need
4464 : : a clone method. */
4465 : 0 : opt_pass * clone () final override { return new pass_peephole2 (m_ctxt); }
4466 : 1481340 : bool gate (function *) final override
4467 : : {
4468 : 1481340 : return (optimize > 0 && flag_peephole2);
4469 : : }
4470 : 966090 : unsigned int execute (function *) final override
4471 : : {
4472 : 966090 : return rest_of_handle_peephole2 ();
4473 : : }
4474 : :
4475 : : }; // class pass_peephole2
4476 : :
4477 : : } // anon namespace
4478 : :
4479 : : rtl_opt_pass *
4480 : 285689 : make_pass_peephole2 (gcc::context *ctxt)
4481 : : {
4482 : 285689 : return new pass_peephole2 (ctxt);
4483 : : }
4484 : :
4485 : : namespace {
4486 : :
4487 : : const pass_data pass_data_split_all_insns =
4488 : : {
4489 : : RTL_PASS, /* type */
4490 : : "split1", /* name */
4491 : : OPTGROUP_NONE, /* optinfo_flags */
4492 : : TV_NONE, /* tv_id */
4493 : : 0, /* properties_required */
4494 : : PROP_rtl_split_insns, /* properties_provided */
4495 : : 0, /* properties_destroyed */
4496 : : 0, /* todo_flags_start */
4497 : : 0, /* todo_flags_finish */
4498 : : };
4499 : :
4500 : : class pass_split_all_insns : public rtl_opt_pass
4501 : : {
4502 : : public:
4503 : 285689 : pass_split_all_insns (gcc::context *ctxt)
4504 : 571378 : : rtl_opt_pass (pass_data_split_all_insns, ctxt)
4505 : : {}
4506 : :
4507 : : /* opt_pass methods: */
4508 : : /* The epiphany backend creates a second instance of this pass, so
4509 : : we need a clone method. */
4510 : 0 : opt_pass * clone () final override
4511 : : {
4512 : 0 : return new pass_split_all_insns (m_ctxt);
4513 : : }
4514 : 1481330 : unsigned int execute (function *) final override
4515 : : {
4516 : 1481330 : split_all_insns ();
4517 : 1481330 : return 0;
4518 : : }
4519 : :
4520 : : }; // class pass_split_all_insns
4521 : :
4522 : : } // anon namespace
4523 : :
4524 : : rtl_opt_pass *
4525 : 285689 : make_pass_split_all_insns (gcc::context *ctxt)
4526 : : {
4527 : 285689 : return new pass_split_all_insns (ctxt);
4528 : : }
4529 : :
4530 : : namespace {
4531 : :
4532 : : const pass_data pass_data_split_after_reload =
4533 : : {
4534 : : RTL_PASS, /* type */
4535 : : "split2", /* name */
4536 : : OPTGROUP_NONE, /* optinfo_flags */
4537 : : TV_NONE, /* tv_id */
4538 : : 0, /* properties_required */
4539 : : 0, /* properties_provided */
4540 : : 0, /* properties_destroyed */
4541 : : 0, /* todo_flags_start */
4542 : : 0, /* todo_flags_finish */
4543 : : };
4544 : :
4545 : : class pass_split_after_reload : public rtl_opt_pass
4546 : : {
4547 : : public:
4548 : 285689 : pass_split_after_reload (gcc::context *ctxt)
4549 : 571378 : : rtl_opt_pass (pass_data_split_after_reload, ctxt)
4550 : : {}
4551 : :
4552 : : /* opt_pass methods: */
4553 : 1481340 : bool gate (function *) final override
4554 : : {
4555 : : /* If optimizing, then go ahead and split insns now. */
4556 : 1481340 : return optimize > 0;
4557 : : }
4558 : :
4559 : 1044976 : unsigned int execute (function *) final override
4560 : : {
4561 : 1044976 : split_all_insns ();
4562 : 1044976 : return 0;
4563 : : }
4564 : :
4565 : : }; // class pass_split_after_reload
4566 : :
4567 : : } // anon namespace
4568 : :
4569 : : rtl_opt_pass *
4570 : 285689 : make_pass_split_after_reload (gcc::context *ctxt)
4571 : : {
4572 : 285689 : return new pass_split_after_reload (ctxt);
4573 : : }
4574 : :
4575 : : static bool
4576 : 2962680 : enable_split_before_sched2 (void)
4577 : : {
4578 : : #ifdef INSN_SCHEDULING
4579 : 2089954 : return optimize > 0 && flag_schedule_insns_after_reload;
4580 : : #else
4581 : : return false;
4582 : : #endif
4583 : : }
4584 : :
4585 : : namespace {
4586 : :
4587 : : const pass_data pass_data_split_before_sched2 =
4588 : : {
4589 : : RTL_PASS, /* type */
4590 : : "split3", /* name */
4591 : : OPTGROUP_NONE, /* optinfo_flags */
4592 : : TV_NONE, /* tv_id */
4593 : : 0, /* properties_required */
4594 : : 0, /* properties_provided */
4595 : : 0, /* properties_destroyed */
4596 : : 0, /* todo_flags_start */
4597 : : 0, /* todo_flags_finish */
4598 : : };
4599 : :
4600 : : class pass_split_before_sched2 : public rtl_opt_pass
4601 : : {
4602 : : public:
4603 : 285689 : pass_split_before_sched2 (gcc::context *ctxt)
4604 : 571378 : : rtl_opt_pass (pass_data_split_before_sched2, ctxt)
4605 : : {}
4606 : :
4607 : : /* opt_pass methods: */
4608 : 1481340 : bool gate (function *) final override
4609 : : {
4610 : 1481340 : return enable_split_before_sched2 ();
4611 : : }
4612 : :
4613 : 966095 : unsigned int execute (function *) final override
4614 : : {
4615 : 966095 : split_all_insns ();
4616 : 966095 : return 0;
4617 : : }
4618 : :
4619 : : }; // class pass_split_before_sched2
4620 : :
4621 : : } // anon namespace
4622 : :
4623 : : rtl_opt_pass *
4624 : 285689 : make_pass_split_before_sched2 (gcc::context *ctxt)
4625 : : {
4626 : 285689 : return new pass_split_before_sched2 (ctxt);
4627 : : }
4628 : :
4629 : : namespace {
4630 : :
4631 : : const pass_data pass_data_split_before_regstack =
4632 : : {
4633 : : RTL_PASS, /* type */
4634 : : "split4", /* name */
4635 : : OPTGROUP_NONE, /* optinfo_flags */
4636 : : TV_NONE, /* tv_id */
4637 : : 0, /* properties_required */
4638 : : 0, /* properties_provided */
4639 : : 0, /* properties_destroyed */
4640 : : 0, /* todo_flags_start */
4641 : : 0, /* todo_flags_finish */
4642 : : };
4643 : :
4644 : : class pass_split_before_regstack : public rtl_opt_pass
4645 : : {
4646 : : public:
4647 : 285689 : pass_split_before_regstack (gcc::context *ctxt)
4648 : 571378 : : rtl_opt_pass (pass_data_split_before_regstack, ctxt)
4649 : : {}
4650 : :
4651 : : /* opt_pass methods: */
4652 : : bool gate (function *) final override;
4653 : 515325 : unsigned int execute (function *) final override
4654 : : {
4655 : 515325 : split_all_insns ();
4656 : 515325 : return 0;
4657 : : }
4658 : :
4659 : : }; // class pass_split_before_regstack
4660 : :
4661 : : bool
4662 : 1481340 : pass_split_before_regstack::gate (function *)
4663 : : {
4664 : : #if HAVE_ATTR_length && defined (STACK_REGS)
4665 : : /* If flow2 creates new instructions which need splitting
4666 : : and scheduling after reload is not done, they might not be
4667 : : split until final which doesn't allow splitting
4668 : : if HAVE_ATTR_length. Selective scheduling can result in
4669 : : further instructions that need splitting. */
4670 : : #ifdef INSN_SCHEDULING
4671 : 2447436 : return !enable_split_before_sched2 () || flag_selective_scheduling2;
4672 : : #else
4673 : : return !enable_split_before_sched2 ();
4674 : : #endif
4675 : : #else
4676 : : return false;
4677 : : #endif
4678 : : }
4679 : :
4680 : : } // anon namespace
4681 : :
4682 : : rtl_opt_pass *
4683 : 285689 : make_pass_split_before_regstack (gcc::context *ctxt)
4684 : : {
4685 : 285689 : return new pass_split_before_regstack (ctxt);
4686 : : }
4687 : :
4688 : : namespace {
4689 : :
4690 : : const pass_data pass_data_split_for_shorten_branches =
4691 : : {
4692 : : RTL_PASS, /* type */
4693 : : "split5", /* name */
4694 : : OPTGROUP_NONE, /* optinfo_flags */
4695 : : TV_NONE, /* tv_id */
4696 : : 0, /* properties_required */
4697 : : 0, /* properties_provided */
4698 : : 0, /* properties_destroyed */
4699 : : 0, /* todo_flags_start */
4700 : : 0, /* todo_flags_finish */
4701 : : };
4702 : :
4703 : : class pass_split_for_shorten_branches : public rtl_opt_pass
4704 : : {
4705 : : public:
4706 : 285689 : pass_split_for_shorten_branches (gcc::context *ctxt)
4707 : 571378 : : rtl_opt_pass (pass_data_split_for_shorten_branches, ctxt)
4708 : : {}
4709 : :
4710 : : /* opt_pass methods: */
4711 : 1481340 : bool gate (function *) final override
4712 : : {
4713 : : /* The placement of the splitting that we do for shorten_branches
4714 : : depends on whether regstack is used by the target or not. */
4715 : : #if HAVE_ATTR_length && !defined (STACK_REGS)
4716 : : return true;
4717 : : #else
4718 : 1481340 : return false;
4719 : : #endif
4720 : : }
4721 : :
4722 : 0 : unsigned int execute (function *) final override
4723 : : {
4724 : 0 : split_all_insns_noflow ();
4725 : 0 : return 0;
4726 : : }
4727 : :
4728 : : }; // class pass_split_for_shorten_branches
4729 : :
4730 : : } // anon namespace
4731 : :
4732 : : rtl_opt_pass *
4733 : 285689 : make_pass_split_for_shorten_branches (gcc::context *ctxt)
4734 : : {
4735 : 285689 : return new pass_split_for_shorten_branches (ctxt);
4736 : : }
4737 : :
4738 : : /* (Re)initialize the target information after a change in target. */
4739 : :
4740 : : void
4741 : 214550 : recog_init ()
4742 : : {
4743 : : /* The information is zero-initialized, so we don't need to do anything
4744 : : first time round. */
4745 : 214550 : if (!this_target_recog->x_initialized)
4746 : : {
4747 : 212442 : this_target_recog->x_initialized = true;
4748 : 212442 : return;
4749 : : }
4750 : 2108 : memset (this_target_recog->x_bool_attr_masks, 0,
4751 : : sizeof (this_target_recog->x_bool_attr_masks));
4752 : 31687456 : for (unsigned int i = 0; i < NUM_INSN_CODES; ++i)
4753 : 31685348 : if (this_target_recog->x_op_alt[i])
4754 : : {
4755 : 29787 : free (this_target_recog->x_op_alt[i]);
4756 : 29787 : this_target_recog->x_op_alt[i] = 0;
4757 : : }
4758 : : }
|