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