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