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