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