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 : :
45 : : #ifndef STACK_POP_CODE
46 : : #if STACK_GROWS_DOWNWARD
47 : : #define STACK_POP_CODE POST_INC
48 : : #else
49 : : #define STACK_POP_CODE POST_DEC
50 : : #endif
51 : : #endif
52 : :
53 : : static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx_insn *, bool);
54 : : static void validate_replace_src_1 (rtx *, void *);
55 : : static rtx_insn *split_insn (rtx_insn *);
56 : :
57 : : struct target_recog default_target_recog;
58 : : #if SWITCHABLE_TARGET
59 : : struct target_recog *this_target_recog = &default_target_recog;
60 : : #endif
61 : :
62 : : /* Nonzero means allow operands to be volatile.
63 : : This should be 0 if you are generating rtl, such as if you are calling
64 : : the functions in optabs.cc and expmed.cc (most of the time).
65 : : This should be 1 if all valid insns need to be recognized,
66 : : such as in reginfo.cc and final.cc and reload.cc.
67 : :
68 : : init_recog and init_recog_no_volatile are responsible for setting this. */
69 : :
70 : : int volatile_ok;
71 : :
72 : : struct recog_data_d recog_data;
73 : :
74 : : /* Contains a vector of operand_alternative structures, such that
75 : : operand OP of alternative A is at index A * n_operands + OP.
76 : : Set up by preprocess_constraints. */
77 : : const operand_alternative *recog_op_alt;
78 : :
79 : : /* Used to provide recog_op_alt for asms. */
80 : : static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS
81 : : * MAX_RECOG_ALTERNATIVES];
82 : :
83 : : /* On return from `constrain_operands', indicate which alternative
84 : : was satisfied. */
85 : :
86 : : int which_alternative;
87 : :
88 : : /* Nonzero after end of reload pass.
89 : : Set to 1 or 0 by toplev.cc.
90 : : Controls the significance of (SUBREG (MEM)). */
91 : :
92 : : int reload_completed;
93 : :
94 : : /* Nonzero after thread_prologue_and_epilogue_insns has run. */
95 : : int epilogue_completed;
96 : :
97 : : /* Initialize data used by the function `recog'.
98 : : This must be called once in the compilation of a function
99 : : before any insn recognition may be done in the function. */
100 : :
101 : : void
102 : 3800215 : init_recog_no_volatile (void)
103 : : {
104 : 3800215 : volatile_ok = 0;
105 : 3800215 : }
106 : :
107 : : void
108 : 7428860 : init_recog (void)
109 : : {
110 : 7428860 : volatile_ok = 1;
111 : 7428860 : }
112 : :
113 : :
114 : : /* Return true if labels in asm operands BODY are LABEL_REFs. */
115 : :
116 : : static bool
117 : 92547312 : asm_labels_ok (rtx body)
118 : : {
119 : 92547312 : rtx asmop;
120 : 92547312 : int i;
121 : :
122 : 92547312 : asmop = extract_asm_operands (body);
123 : 92547312 : if (asmop == NULL_RTX)
124 : : return true;
125 : :
126 : 505555 : for (i = 0; i < ASM_OPERANDS_LABEL_LENGTH (asmop); i++)
127 : 4889 : if (GET_CODE (ASM_OPERANDS_LABEL (asmop, i)) != LABEL_REF)
128 : : return false;
129 : :
130 : : return true;
131 : : }
132 : :
133 : : /* Check that X is an insn-body for an `asm' with operands
134 : : and that the operands mentioned in it are legitimate. */
135 : :
136 : : bool
137 : 92547312 : check_asm_operands (rtx x)
138 : : {
139 : 92547312 : int noperands;
140 : 92547312 : rtx *operands;
141 : 92547312 : const char **constraints;
142 : 92547312 : int i;
143 : :
144 : 92547312 : if (!asm_labels_ok (x))
145 : : return false;
146 : :
147 : : /* Post-reload, be more strict with things. */
148 : 92547312 : if (reload_completed)
149 : : {
150 : : /* ??? Doh! We've not got the wrapping insn. Cook one up. */
151 : 3600 : rtx_insn *insn = make_insn_raw (x);
152 : 3600 : extract_insn (insn);
153 : 3600 : constrain_operands (1, get_enabled_alternatives (insn));
154 : 3600 : return which_alternative >= 0;
155 : : }
156 : :
157 : 92543712 : noperands = asm_noperands (x);
158 : 92543712 : if (noperands < 0)
159 : : return false;
160 : 478304 : if (noperands == 0)
161 : : return true;
162 : :
163 : 411774 : operands = XALLOCAVEC (rtx, noperands);
164 : 411774 : constraints = XALLOCAVEC (const char *, noperands);
165 : :
166 : 411774 : decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
167 : :
168 : 1920911 : for (i = 0; i < noperands; i++)
169 : : {
170 : 1846990 : const char *c = constraints[i];
171 : 1846990 : if (c[0] == '%')
172 : 3575 : c++;
173 : 1846990 : if (! asm_operand_ok (operands[i], c, constraints))
174 : : return false;
175 : : }
176 : :
177 : : return true;
178 : : }
179 : :
180 : : /* Static data for the next two routines. */
181 : :
182 : : struct change_t
183 : : {
184 : : rtx object;
185 : : int old_code;
186 : : int old_len;
187 : : bool unshare;
188 : : rtx *loc;
189 : : rtx old;
190 : : };
191 : :
192 : : static change_t *changes;
193 : : static int changes_allocated;
194 : :
195 : : static int num_changes = 0;
196 : : static int temporarily_undone_changes = 0;
197 : :
198 : : /* Validate a proposed change to OBJECT. LOC is the location in the rtl
199 : : at which NEW_RTX will be placed. If NEW_LEN is >= 0, XVECLEN (NEW_RTX, 0)
200 : : will also be changed to NEW_LEN, which is no greater than the current
201 : : XVECLEN. If OBJECT is zero, no validation is done, the change is
202 : : simply made.
203 : :
204 : : Two types of objects are supported: If OBJECT is a MEM, memory_address_p
205 : : will be called with the address and mode as parameters. If OBJECT is
206 : : an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with
207 : : the change in place.
208 : :
209 : : IN_GROUP is nonzero if this is part of a group of changes that must be
210 : : performed as a group. In that case, the changes will be stored. The
211 : : function `apply_change_group' will validate and apply the changes.
212 : :
213 : : If IN_GROUP is zero, this is a single change. Try to recognize the insn
214 : : or validate the memory reference with the change applied. If the result
215 : : is not valid for the machine, suppress the change and return false.
216 : : Otherwise, perform the change and return true. */
217 : :
218 : : static bool
219 : 1543389647 : validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group,
220 : : bool unshare, int new_len = -1)
221 : : {
222 : 1543389647 : gcc_assert (temporarily_undone_changes == 0);
223 : 1543389647 : rtx old = *loc;
224 : :
225 : : /* Single-element parallels aren't valid and won't match anything.
226 : : Replace them with the single element. */
227 : 1543389647 : if (new_len == 1 && GET_CODE (new_rtx) == PARALLEL)
228 : : {
229 : 2963516 : new_rtx = XVECEXP (new_rtx, 0, 0);
230 : 2963516 : new_len = -1;
231 : : }
232 : :
233 : 126707966 : if ((old == new_rtx || rtx_equal_p (old, new_rtx))
234 : 1546243275 : && (new_len < 0 || XVECLEN (new_rtx, 0) == new_len))
235 : : return true;
236 : :
237 : 123946634 : gcc_assert ((in_group != 0 || num_changes == 0)
238 : : && (new_len < 0 || new_rtx == *loc));
239 : :
240 : 123946634 : *loc = new_rtx;
241 : :
242 : : /* Save the information describing this change. */
243 : 123946634 : if (num_changes >= changes_allocated)
244 : : {
245 : 156368 : if (changes_allocated == 0)
246 : : /* This value allows for repeated substitutions inside complex
247 : : indexed addresses, or changes in up to 5 insns. */
248 : 156351 : changes_allocated = MAX_RECOG_OPERANDS * 5;
249 : : else
250 : 17 : changes_allocated *= 2;
251 : :
252 : 156368 : changes = XRESIZEVEC (change_t, changes, changes_allocated);
253 : : }
254 : :
255 : 123946634 : changes[num_changes].object = object;
256 : 123946634 : changes[num_changes].loc = loc;
257 : 123946634 : changes[num_changes].old = old;
258 : 123946634 : changes[num_changes].old_len = (new_len >= 0 ? XVECLEN (new_rtx, 0) : -1);
259 : 123946634 : changes[num_changes].unshare = unshare;
260 : :
261 : 123946634 : if (new_len >= 0)
262 : 92296 : XVECLEN (new_rtx, 0) = new_len;
263 : :
264 : 123946634 : if (object && !MEM_P (object))
265 : : {
266 : : /* Set INSN_CODE to force rerecognition of insn. Save old code in
267 : : case invalid. */
268 : 100897225 : changes[num_changes].old_code = INSN_CODE (object);
269 : 100897225 : INSN_CODE (object) = -1;
270 : : }
271 : :
272 : 123946634 : num_changes++;
273 : :
274 : : /* If we are making a group of changes, return 1. Otherwise, validate the
275 : : change group we made. */
276 : :
277 : 123946634 : if (in_group)
278 : : return true;
279 : : else
280 : 16269993 : return apply_change_group ();
281 : : }
282 : :
283 : : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
284 : : UNSHARE to false. */
285 : :
286 : : bool
287 : 1309293313 : validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
288 : : {
289 : 1309293313 : return validate_change_1 (object, loc, new_rtx, in_group, false);
290 : : }
291 : :
292 : : /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
293 : : UNSHARE to true. */
294 : :
295 : : bool
296 : 227619530 : validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
297 : : {
298 : 227619530 : return validate_change_1 (object, loc, new_rtx, in_group, true);
299 : : }
300 : :
301 : : /* Change XVECLEN (*LOC, 0) to NEW_LEN. OBJECT, IN_GROUP and the return
302 : : value are as for validate_change_1. */
303 : :
304 : : bool
305 : 6476804 : validate_change_xveclen (rtx object, rtx *loc, int new_len, bool in_group)
306 : : {
307 : 6476804 : return validate_change_1 (object, loc, *loc, in_group, false, new_len);
308 : : }
309 : :
310 : : /* Keep X canonicalized if some changes have made it non-canonical; only
311 : : modifies the operands of X, not (for example) its code. Simplifications
312 : : are not the job of this routine.
313 : :
314 : : Return true if anything was changed. */
315 : : bool
316 : 1952882 : canonicalize_change_group (rtx_insn *insn, rtx x)
317 : : {
318 : 1952882 : if (COMMUTATIVE_P (x)
319 : 1952882 : && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
320 : : {
321 : : /* Oops, the caller has made X no longer canonical.
322 : : Let's redo the changes in the correct order. */
323 : 179587 : rtx tem = XEXP (x, 0);
324 : 179587 : validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
325 : 179587 : validate_unshare_change (insn, &XEXP (x, 1), tem, 1);
326 : 179587 : return true;
327 : : }
328 : : else
329 : 1773295 : return false;
330 : : }
331 : :
332 : : /* Check if REG_INC argument in *data overlaps a stored REG. */
333 : :
334 : : static void
335 : 0 : check_invalid_inc_dec (rtx reg, const_rtx, void *data)
336 : : {
337 : 0 : rtx *pinc = (rtx *) data;
338 : 0 : if (*pinc == NULL_RTX || MEM_P (reg))
339 : : return;
340 : 0 : if (reg_overlap_mentioned_p (reg, *pinc))
341 : 0 : *pinc = NULL_RTX;
342 : : }
343 : :
344 : : /* This subroutine of apply_change_group verifies whether the changes to INSN
345 : : were valid; i.e. whether INSN can still be recognized.
346 : :
347 : : If IN_GROUP is true clobbers which have to be added in order to
348 : : match the instructions will be added to the current change group.
349 : : Otherwise the changes will take effect immediately. */
350 : :
351 : : bool
352 : 70522564 : insn_invalid_p (rtx_insn *insn, bool in_group)
353 : : {
354 : 70522564 : rtx pat = PATTERN (insn);
355 : 70522564 : int num_clobbers = 0;
356 : : /* If we are before reload and the pattern is a SET, see if we can add
357 : : clobbers. */
358 : 70522564 : int icode = recog (pat, insn,
359 : 70522564 : (GET_CODE (pat) == SET
360 : 60994983 : && ! reload_completed
361 : 31883684 : && ! reload_in_progress)
362 : : ? &num_clobbers : 0);
363 : 70522564 : bool is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
364 : :
365 : :
366 : : /* If this is an asm and the operand aren't legal, then fail. Likewise if
367 : : this is not an asm and the insn wasn't recognized. */
368 : 276651 : if ((is_asm && ! check_asm_operands (PATTERN (insn)))
369 : 70265160 : || (!is_asm && icode < 0))
370 : 16634530 : return true;
371 : :
372 : : /* If we have to add CLOBBERs, fail if we have to add ones that reference
373 : : hard registers since our callers can't know if they are live or not.
374 : : Otherwise, add them. */
375 : 53888034 : if (num_clobbers > 0)
376 : : {
377 : 733464 : rtx newpat;
378 : :
379 : 733464 : if (added_clobbers_hard_reg_p (icode))
380 : : return true;
381 : :
382 : 501 : newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
383 : 501 : XVECEXP (newpat, 0, 0) = pat;
384 : 501 : add_clobbers (newpat, icode);
385 : 501 : if (in_group)
386 : 500 : validate_change (insn, &PATTERN (insn), newpat, 1);
387 : : else
388 : 1 : PATTERN (insn) = pat = newpat;
389 : : }
390 : :
391 : : /* After reload, verify that all constraints are satisfied. */
392 : 53155071 : if (reload_completed)
393 : : {
394 : 29197757 : extract_insn (insn);
395 : :
396 : 29197757 : if (! constrain_operands (1, get_preferred_alternatives (insn)))
397 : : return true;
398 : : }
399 : :
400 : : /* Punt if REG_INC argument overlaps some stored REG. */
401 : 53137063 : for (rtx link = FIND_REG_INC_NOTE (insn, NULL_RTX);
402 : 53137063 : link; link = XEXP (link, 1))
403 : : if (REG_NOTE_KIND (link) == REG_INC)
404 : : {
405 : : rtx reg = XEXP (link, 0);
406 : : note_stores (insn, check_invalid_inc_dec, ®);
407 : : if (reg == NULL_RTX)
408 : : return true;
409 : : }
410 : :
411 : 53137063 : INSN_CODE (insn) = icode;
412 : 53137063 : return false;
413 : : }
414 : :
415 : : /* Return number of changes made and not validated yet. */
416 : : int
417 : 4635695 : num_changes_pending (void)
418 : : {
419 : 4635695 : return num_changes;
420 : : }
421 : :
422 : : /* Tentatively apply the changes numbered NUM and up.
423 : : Return true if all changes are valid, false otherwise. */
424 : :
425 : : bool
426 : 669151138 : verify_changes (int num)
427 : : {
428 : 669151138 : int i;
429 : 669151138 : rtx last_validated = NULL_RTX;
430 : :
431 : : /* The changes have been applied and all INSN_CODEs have been reset to force
432 : : rerecognition.
433 : :
434 : : The changes are valid if we aren't given an object, or if we are
435 : : given a MEM and it still is a valid address, or if this is in insn
436 : : and it is recognized. In the latter case, if reload has completed,
437 : : we also require that the operands meet the constraints for
438 : : the insn. */
439 : :
440 : 719607862 : for (i = num; i < num_changes; i++)
441 : : {
442 : 65347342 : rtx object = changes[i].object;
443 : :
444 : : /* If there is no object to test or if it is the same as the one we
445 : : already tested, ignore it. */
446 : 65347342 : if (object == 0 || object == last_validated)
447 : 5912841 : continue;
448 : :
449 : 59434501 : if (MEM_P (object))
450 : : {
451 : 23824 : if (! memory_address_addr_space_p (GET_MODE (object),
452 : : XEXP (object, 0),
453 : 11912 : MEM_ADDR_SPACE (object)))
454 : : break;
455 : : }
456 : 59422589 : else if (/* changes[i].old might be zero, e.g. when putting a
457 : : REG_FRAME_RELATED_EXPR into a previously empty list. */
458 : 59422589 : changes[i].old
459 : 59422589 : && REG_P (changes[i].old)
460 : 22390013 : && asm_noperands (PATTERN (object)) > 0
461 : 59687320 : && register_asm_p (changes[i].old))
462 : : {
463 : : /* Don't allow changes of hard register operands to inline
464 : : assemblies if they have been defined as register asm ("x"). */
465 : : break;
466 : : }
467 : 59422588 : else if (DEBUG_INSN_P (object))
468 : 705051 : continue;
469 : 58717537 : else if (insn_invalid_p (as_a <rtx_insn *> (object), true))
470 : : {
471 : 17385490 : rtx pat = PATTERN (object);
472 : :
473 : : /* Perhaps we couldn't recognize the insn because there were
474 : : extra CLOBBERs at the end. If so, try to re-recognize
475 : : without the last CLOBBER (later iterations will cause each of
476 : : them to be eliminated, in turn). But don't do this if we
477 : : have an ASM_OPERAND. */
478 : 17385490 : if (GET_CODE (pat) == PARALLEL
479 : 4135569 : && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
480 : 20137575 : && asm_noperands (PATTERN (object)) < 0)
481 : : {
482 : 2494683 : rtx newpat;
483 : :
484 : 2494683 : if (XVECLEN (pat, 0) == 2)
485 : 2100696 : newpat = XVECEXP (pat, 0, 0);
486 : : else
487 : : {
488 : 393987 : int j;
489 : :
490 : 393987 : newpat
491 : 393987 : = gen_rtx_PARALLEL (VOIDmode,
492 : : rtvec_alloc (XVECLEN (pat, 0) - 1));
493 : 1213558 : for (j = 0; j < XVECLEN (newpat, 0); j++)
494 : 819571 : XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j);
495 : : }
496 : :
497 : : /* Add a new change to this group to replace the pattern
498 : : with this new pattern. Then consider this change
499 : : as having succeeded. The change we added will
500 : : cause the entire call to fail if things remain invalid.
501 : :
502 : : Note that this can lose if a later change than the one
503 : : we are processing specified &XVECEXP (PATTERN (object), 0, X)
504 : : but this shouldn't occur. */
505 : :
506 : 2494683 : validate_change (object, &PATTERN (object), newpat, 1);
507 : 2494683 : continue;
508 : 2494683 : }
509 : 14890807 : else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
510 : 14890543 : || GET_CODE (pat) == VAR_LOCATION)
511 : : /* If this insn is a CLOBBER or USE, it is always valid, but is
512 : : never recognized. */
513 : 264 : continue;
514 : : else
515 : : break;
516 : : }
517 : : last_validated = object;
518 : : }
519 : :
520 : 669151138 : return (i == num_changes);
521 : : }
522 : :
523 : : /* A group of changes has previously been issued with validate_change
524 : : and verified with verify_changes. Call df_insn_rescan for each of
525 : : the insn changed and clear num_changes. */
526 : :
527 : : void
528 : 653372611 : confirm_change_group (void)
529 : : {
530 : 653372611 : int i;
531 : 653372611 : rtx last_object = NULL;
532 : :
533 : 653372611 : gcc_assert (temporarily_undone_changes == 0);
534 : 705273932 : for (i = 0; i < num_changes; i++)
535 : : {
536 : 51901321 : rtx object = changes[i].object;
537 : :
538 : 51901321 : if (changes[i].unshare)
539 : 11477154 : *changes[i].loc = copy_rtx (*changes[i].loc);
540 : :
541 : : /* Avoid unnecessary rescanning when multiple changes to same instruction
542 : : are made. */
543 : 51901321 : if (object)
544 : : {
545 : 49319125 : if (object != last_object && last_object && INSN_P (last_object))
546 : 1865177 : df_insn_rescan (as_a <rtx_insn *> (last_object));
547 : : last_object = object;
548 : : }
549 : : }
550 : :
551 : 653372611 : if (last_object && INSN_P (last_object))
552 : 42487051 : df_insn_rescan (as_a <rtx_insn *> (last_object));
553 : 653372611 : num_changes = 0;
554 : 653372611 : }
555 : :
556 : : /* Apply a group of changes previously issued with `validate_change'.
557 : : If all changes are valid, call confirm_change_group and return true,
558 : : otherwise, call cancel_changes and return false. */
559 : :
560 : : bool
561 : 661659969 : apply_change_group (void)
562 : : {
563 : 661659969 : if (verify_changes (0))
564 : : {
565 : 650150123 : confirm_change_group ();
566 : 650150123 : return true;
567 : : }
568 : : else
569 : : {
570 : 11509846 : cancel_changes (0);
571 : 11509846 : return false;
572 : : }
573 : : }
574 : :
575 : :
576 : : /* Return the number of changes so far in the current group. */
577 : :
578 : : int
579 : 352405258 : num_validated_changes (void)
580 : : {
581 : 352405258 : return num_changes;
582 : : }
583 : :
584 : : /* Retract the changes numbered NUM and up. */
585 : :
586 : : void
587 : 116505969 : cancel_changes (int num)
588 : : {
589 : 116505969 : gcc_assert (temporarily_undone_changes == 0);
590 : 116505969 : int i;
591 : :
592 : : /* Back out all the changes. Do this in the opposite order in which
593 : : they were made. */
594 : 188551282 : for (i = num_changes - 1; i >= num; i--)
595 : : {
596 : 72045313 : if (changes[i].old_len >= 0)
597 : 92296 : XVECLEN (*changes[i].loc, 0) = changes[i].old_len;
598 : : else
599 : 71953017 : *changes[i].loc = changes[i].old;
600 : 72045313 : if (changes[i].object && !MEM_P (changes[i].object))
601 : 51589938 : INSN_CODE (changes[i].object) = changes[i].old_code;
602 : : }
603 : 116505969 : num_changes = num;
604 : 116505969 : }
605 : :
606 : : /* Swap the status of change NUM from being applied to not being applied,
607 : : or vice versa. */
608 : :
609 : : static void
610 : 26995906 : swap_change (int num)
611 : : {
612 : 26995906 : if (changes[num].old_len >= 0)
613 : 20 : std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len);
614 : : else
615 : 26995886 : std::swap (*changes[num].loc, changes[num].old);
616 : 26995906 : if (changes[num].object && !MEM_P (changes[num].object))
617 : 26995906 : std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
618 : 26995906 : }
619 : :
620 : : /* Temporarily undo all the changes numbered NUM and up, with a view
621 : : to reapplying them later. The next call to the changes machinery
622 : : must be:
623 : :
624 : : redo_changes (NUM)
625 : :
626 : : otherwise things will end up in an invalid state. */
627 : :
628 : : void
629 : 9166427 : temporarily_undo_changes (int num)
630 : : {
631 : 9166427 : gcc_assert (temporarily_undone_changes == 0 && num <= num_changes);
632 : 22664380 : for (int i = num_changes - 1; i >= num; i--)
633 : 13497953 : swap_change (i);
634 : 9166427 : temporarily_undone_changes = num_changes - num;
635 : 9166427 : }
636 : :
637 : : /* Redo the changes that were temporarily undone by:
638 : :
639 : : temporarily_undo_changes (NUM). */
640 : :
641 : : void
642 : 9166427 : redo_changes (int num)
643 : : {
644 : 9166427 : gcc_assert (temporarily_undone_changes == num_changes - num);
645 : 22664380 : for (int i = num; i < num_changes; ++i)
646 : 13497953 : swap_change (i);
647 : 9166427 : temporarily_undone_changes = 0;
648 : 9166427 : }
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 : 11726742 : simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
656 : : machine_mode op0_mode)
657 : : {
658 : 11726742 : rtx x = *loc;
659 : 11726742 : enum rtx_code code = GET_CODE (x);
660 : 11726742 : rtx new_rtx = NULL_RTX;
661 : 11726742 : scalar_int_mode is_mode;
662 : :
663 : 11726742 : if (SWAPPABLE_OPERANDS_P (x)
664 : 11726742 : && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
665 : : {
666 : 606819 : validate_unshare_change (object, loc,
667 : 606819 : 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 : 606819 : x = *loc;
672 : 606819 : code = GET_CODE (x);
673 : : }
674 : :
675 : : /* Canonicalize arithmetics with all constant operands. */
676 : 11726742 : switch (GET_RTX_CLASS (code))
677 : : {
678 : 826587 : case RTX_UNARY:
679 : 826587 : if (CONSTANT_P (XEXP (x, 0)))
680 : 622110 : new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0),
681 : : op0_mode);
682 : : break;
683 : 6134963 : case RTX_COMM_ARITH:
684 : 6134963 : case RTX_BIN_ARITH:
685 : 6134963 : if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
686 : 432487 : new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0),
687 : : XEXP (x, 1));
688 : : break;
689 : 99926 : case RTX_COMPARE:
690 : 99926 : case RTX_COMM_COMPARE:
691 : 99926 : if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
692 : 2878 : 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 : 1057475 : if (new_rtx)
699 : : {
700 : 918820 : validate_change (object, loc, new_rtx, 1);
701 : 918820 : return;
702 : : }
703 : :
704 : 10807922 : switch (code)
705 : : {
706 : 2098447 : 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 : 2098447 : if (CONST_INT_P (XEXP (x, 1)) && XEXP (x, 1) == to)
712 : 189311 : validate_change (object, loc,
713 : : simplify_gen_binary
714 : 189311 : (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
715 : : break;
716 : 425626 : case MINUS:
717 : 425626 : if (CONST_SCALAR_INT_P (XEXP (x, 1)))
718 : 22648 : validate_change (object, loc,
719 : : simplify_gen_binary
720 : 22648 : (PLUS, GET_MODE (x), XEXP (x, 0),
721 : : simplify_gen_unary (NEG,
722 : : GET_MODE (x), XEXP (x, 1),
723 : 22648 : GET_MODE (x))), 1);
724 : : break;
725 : 150771 : case ZERO_EXTEND:
726 : 150771 : case SIGN_EXTEND:
727 : 150771 : 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 : 121527 : case SUBREG:
739 : : /* All subregs possible to simplify should be simplified. */
740 : 121527 : new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
741 : 121527 : SUBREG_BYTE (x));
742 : :
743 : : /* Subregs of VOIDmode operands are incorrect. */
744 : 121527 : if (!new_rtx && GET_MODE (SUBREG_REG (x)) == VOIDmode)
745 : 2 : new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
746 : 19050 : if (new_rtx)
747 : 102479 : validate_change (object, loc, new_rtx, 1);
748 : : break;
749 : 5825 : case ZERO_EXTRACT:
750 : 5825 : 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 : 5825 : if (MEM_P (XEXP (x, 0))
757 : 421 : && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &is_mode)
758 : 421 : && CONST_INT_P (XEXP (x, 1))
759 : 421 : && CONST_INT_P (XEXP (x, 2))
760 : 245 : && !mode_dependent_address_p (XEXP (XEXP (x, 0), 0),
761 : 245 : MEM_ADDR_SPACE (XEXP (x, 0)))
762 : 6070 : && !MEM_VOLATILE_P (XEXP (x, 0)))
763 : : {
764 : 245 : int pos = INTVAL (XEXP (x, 2));
765 : 245 : machine_mode new_mode = is_mode;
766 : 245 : if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
767 : 0 : new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
768 : 245 : else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
769 : 0 : new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
770 : 245 : scalar_int_mode wanted_mode = (new_mode == VOIDmode
771 : 245 : ? word_mode
772 : 245 : : as_a <scalar_int_mode> (new_mode));
773 : :
774 : : /* If we have a narrower mode, we can do something. */
775 : 735 : 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 : 67828211 : validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx_insn *object,
810 : : bool simplify)
811 : : {
812 : 67828211 : int i, j;
813 : 67828211 : const char *fmt;
814 : 67828211 : rtx x = *loc;
815 : 67828211 : enum rtx_code code;
816 : 67828211 : machine_mode op0_mode = VOIDmode;
817 : 67828211 : int prev_changes = num_changes;
818 : :
819 : 67828211 : if (!x)
820 : : return;
821 : :
822 : 67828211 : code = GET_CODE (x);
823 : 67828211 : fmt = GET_RTX_FORMAT (code);
824 : 67828211 : if (fmt[0] == 'e')
825 : 23047583 : 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 : 67828211 : if (x == from
832 : 53124491 : || (REG_P (x) && REG_P (from)
833 : 15083264 : && GET_MODE (x) == GET_MODE (from)
834 : 9721433 : && REGNO (x) == REGNO (from))
835 : 120952699 : || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
836 : 9721430 : && rtx_equal_p (x, from)))
837 : : {
838 : 14703723 : validate_unshare_change (object, loc, to, 1);
839 : 14703723 : 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 : 53124488 : if (GET_CODE (x) == PARALLEL)
848 : : {
849 : 1202928 : for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
850 : : {
851 : 890393 : if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
852 : 35410 : && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
853 : : {
854 : : /* Verify that operands are really shared. */
855 : 193 : 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 : 193 : validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
859 : : from, to, object, simplify);
860 : : }
861 : : else
862 : 890200 : validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
863 : : simplify);
864 : : }
865 : : }
866 : : else
867 : 135663750 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
868 : : {
869 : 82851797 : if (fmt[i] == 'e')
870 : 39236591 : validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
871 : 43615206 : else if (fmt[i] == 'E')
872 : 7478736 : for (j = XVECLEN (x, i) - 1; j >= 0; j--)
873 : 3973556 : 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 : 53124488 : 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 : 11726833 : if (fmt[0] == 'e' && GET_MODE (XEXP (x, 0)) != VOIDmode)
885 : 8630305 : 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 : 11726833 : if (simplify)
890 : 11726742 : 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 : 1974709 : validate_replace_rtx (rtx from, rtx to, rtx_insn *insn)
909 : : {
910 : 1974709 : validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
911 : 1974709 : 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 : 116 : validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
930 : : rtx_insn *insn)
931 : : {
932 : 116 : validate_replace_rtx_1 (where, from, to, insn, false);
933 : 116 : 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 : 21752825 : validate_replace_src_1 (rtx *x, void *data)
961 : : {
962 : 21752825 : struct validate_replace_src_data *d
963 : : = (struct validate_replace_src_data *) data;
964 : :
965 : 21752825 : validate_replace_rtx_1 (x, d->from, d->to, d->insn, true);
966 : 21752825 : }
967 : :
968 : : /* Try replacing every occurrence of FROM in INSN with TO, avoiding
969 : : SET_DESTs. */
970 : :
971 : : void
972 : 15324906 : validate_replace_src_group (rtx from, rtx to, rtx_insn *insn)
973 : : {
974 : 15324906 : struct validate_replace_src_data d;
975 : :
976 : 15324906 : d.from = from;
977 : 15324906 : d.to = to;
978 : 15324906 : d.insn = insn;
979 : 15324906 : note_uses (&PATTERN (insn), validate_replace_src_1, &d);
980 : 15324906 : }
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 : 11336682 : insn_propagation::apply_to_mem_1 (rtx mem)
1027 : : {
1028 : 11336682 : auto old_num_changes = num_validated_changes ();
1029 : 11336682 : mem_depth += 1;
1030 : 11336682 : bool res = apply_to_rvalue_1 (&XEXP (mem, 0));
1031 : 11336682 : mem_depth -= 1;
1032 : 11336682 : if (!res)
1033 : : return false;
1034 : :
1035 : 11336310 : if (old_num_changes != num_validated_changes ()
1036 : 2819174 : && should_check_mems
1037 : 14155479 : && !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 : 100080484 : insn_propagation::apply_to_rvalue_1 (rtx *loc)
1048 : : {
1049 : 100080484 : rtx x = *loc;
1050 : 100080484 : enum rtx_code code = GET_CODE (x);
1051 : 100080484 : machine_mode mode = GET_MODE (x);
1052 : :
1053 : 100080484 : auto old_num_changes = num_validated_changes ();
1054 : 100080484 : if (from && GET_CODE (x) == GET_CODE (from) && rtx_equal_p (x, from))
1055 : : {
1056 : : /* Don't replace register asms in asm statements; we mustn't
1057 : : change the user's register allocation. */
1058 : 24212271 : if (REG_P (x)
1059 : 24188123 : && HARD_REGISTER_P (x)
1060 : 514862 : && register_asm_p (x)
1061 : 24213064 : && asm_noperands (PATTERN (insn)) > 0)
1062 : : return false;
1063 : :
1064 : 24211632 : if (should_unshare)
1065 : 24211632 : validate_unshare_change (insn, loc, to, 1);
1066 : : else
1067 : 0 : validate_change (insn, loc, to, 1);
1068 : 24211632 : if (mem_depth && !REG_P (to) && !CONSTANT_P (to))
1069 : : {
1070 : : /* We're substituting into an address, but TO will have the
1071 : : form expected outside an address. Canonicalize it if
1072 : : necessary. */
1073 : 1819904 : insn_propagation subprop (insn);
1074 : 1819904 : subprop.mem_depth += 1;
1075 : 1819904 : if (!subprop.apply_to_rvalue (loc))
1076 : 0 : gcc_unreachable ();
1077 : 1819904 : if (should_unshare
1078 : 1819904 : && num_validated_changes () != old_num_changes + 1)
1079 : : {
1080 : : /* TO is owned by someone else, so create a copy and
1081 : : return TO to its original form. */
1082 : 124581 : rtx to = copy_rtx (*loc);
1083 : 124581 : cancel_changes (old_num_changes);
1084 : 124581 : validate_change (insn, loc, to, 1);
1085 : : }
1086 : : }
1087 : 24211632 : num_replacements += 1;
1088 : 24211632 : should_unshare = true;
1089 : 24211632 : result_flags |= UNSIMPLIFIED;
1090 : 24211632 : return true;
1091 : : }
1092 : :
1093 : : /* Recursively apply the substitution and see if we can simplify
1094 : : the result. This specifically shouldn't use simplify_gen_* for
1095 : : speculative simplifications, since we want to avoid generating new
1096 : : expressions where possible. */
1097 : 75868213 : auto old_result_flags = result_flags;
1098 : 75868213 : rtx newx = NULL_RTX;
1099 : 75868213 : bool recurse_p = false;
1100 : 75868213 : switch (GET_RTX_CLASS (code))
1101 : : {
1102 : 1432336 : case RTX_UNARY:
1103 : 1432336 : {
1104 : 1432336 : machine_mode op0_mode = GET_MODE (XEXP (x, 0));
1105 : 1432336 : if (!apply_to_rvalue_1 (&XEXP (x, 0)))
1106 : : return false;
1107 : 1409095 : if (from && old_num_changes == num_validated_changes ())
1108 : : return true;
1109 : :
1110 : 1117088 : newx = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
1111 : 1117088 : break;
1112 : : }
1113 : :
1114 : 18788519 : case RTX_BIN_ARITH:
1115 : 18788519 : case RTX_COMM_ARITH:
1116 : 18788519 : {
1117 : 18788519 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1118 : 18788519 : || !apply_to_rvalue_1 (&XEXP (x, 1)))
1119 : 157774 : return false;
1120 : 18630745 : if (from && old_num_changes == num_validated_changes ())
1121 : : return true;
1122 : :
1123 : 13374179 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
1124 : 13374179 : && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
1125 : 1256207 : newx = simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
1126 : : else
1127 : 12117972 : newx = simplify_binary_operation (code, mode,
1128 : : XEXP (x, 0), XEXP (x, 1));
1129 : : break;
1130 : : }
1131 : :
1132 : 950381 : case RTX_COMPARE:
1133 : 950381 : case RTX_COMM_COMPARE:
1134 : 950381 : {
1135 : 1900762 : machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
1136 : 950381 : ? GET_MODE (XEXP (x, 0))
1137 : 225 : : GET_MODE (XEXP (x, 1)));
1138 : 950381 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1139 : 950381 : || !apply_to_rvalue_1 (&XEXP (x, 1)))
1140 : 1151 : return false;
1141 : 949230 : if (from && old_num_changes == num_validated_changes ())
1142 : : return true;
1143 : :
1144 : 597909 : newx = simplify_relational_operation (code, mode, op_mode,
1145 : : XEXP (x, 0), XEXP (x, 1));
1146 : 597909 : break;
1147 : : }
1148 : :
1149 : 603041 : case RTX_TERNARY:
1150 : 603041 : case RTX_BITFIELD_OPS:
1151 : 603041 : {
1152 : 603041 : machine_mode op0_mode = GET_MODE (XEXP (x, 0));
1153 : 603041 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1154 : 601364 : || !apply_to_rvalue_1 (&XEXP (x, 1))
1155 : 1188373 : || !apply_to_rvalue_1 (&XEXP (x, 2)))
1156 : 19518 : return false;
1157 : 583523 : if (from && old_num_changes == num_validated_changes ())
1158 : : return true;
1159 : :
1160 : 531562 : newx = simplify_ternary_operation (code, mode, op0_mode,
1161 : : XEXP (x, 0), XEXP (x, 1),
1162 : : XEXP (x, 2));
1163 : 531562 : break;
1164 : : }
1165 : :
1166 : 8427203 : case RTX_EXTRA:
1167 : 8427203 : if (code == SUBREG)
1168 : : {
1169 : 1652700 : machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
1170 : 1652700 : if (!apply_to_rvalue_1 (&SUBREG_REG (x)))
1171 : : return false;
1172 : 1652694 : if (from && old_num_changes == num_validated_changes ())
1173 : : return true;
1174 : :
1175 : 1176819 : rtx inner = SUBREG_REG (x);
1176 : 1176819 : newx = simplify_subreg (mode, inner, inner_mode, SUBREG_BYTE (x));
1177 : : /* Reject the same cases that simplify_gen_subreg would. */
1178 : 1176819 : if (!newx
1179 : 1176819 : && (GET_CODE (inner) == SUBREG
1180 : 654577 : || GET_CODE (inner) == CONCAT
1181 : 643996 : || GET_MODE (inner) == VOIDmode
1182 : 643995 : || !validate_subreg (mode, inner_mode,
1183 : 643995 : inner, SUBREG_BYTE (x))))
1184 : : {
1185 : 10582 : failure_reason = "would create an invalid subreg";
1186 : 10582 : return false;
1187 : : }
1188 : : break;
1189 : : }
1190 : : else
1191 : : recurse_p = true;
1192 : : break;
1193 : :
1194 : 23359631 : case RTX_OBJ:
1195 : 23359631 : if (code == LO_SUM)
1196 : : {
1197 : 0 : if (!apply_to_rvalue_1 (&XEXP (x, 0))
1198 : 0 : || !apply_to_rvalue_1 (&XEXP (x, 1)))
1199 : 0 : return false;
1200 : 0 : if (from && old_num_changes == num_validated_changes ())
1201 : : return true;
1202 : :
1203 : : /* (lo_sum (high x) y) -> y where x and y have the same base. */
1204 : 0 : rtx op0 = XEXP (x, 0);
1205 : 0 : rtx op1 = XEXP (x, 1);
1206 : 0 : if (GET_CODE (op0) == HIGH)
1207 : : {
1208 : 0 : rtx base0, base1, offset0, offset1;
1209 : 0 : split_const (XEXP (op0, 0), &base0, &offset0);
1210 : 0 : split_const (op1, &base1, &offset1);
1211 : 0 : if (rtx_equal_p (base0, base1))
1212 : 0 : newx = op1;
1213 : : }
1214 : : }
1215 : 23359631 : else if (code == REG)
1216 : : {
1217 : 16074136 : if (from && REG_P (from) && reg_overlap_mentioned_p (x, from))
1218 : : {
1219 : 487 : failure_reason = "inexact register overlap";
1220 : 487 : return false;
1221 : : }
1222 : : }
1223 : 7285495 : else if (code == MEM)
1224 : 7222688 : return apply_to_mem_1 (x);
1225 : : else
1226 : : recurse_p = true;
1227 : : break;
1228 : :
1229 : : case RTX_CONST_OBJ:
1230 : : break;
1231 : :
1232 : 558002 : case RTX_AUTOINC:
1233 : 558002 : if (from && reg_overlap_mentioned_p (XEXP (x, 0), from))
1234 : : {
1235 : 0 : failure_reason = "is subject to autoinc";
1236 : 0 : return false;
1237 : : }
1238 : : recurse_p = true;
1239 : : break;
1240 : :
1241 : 0 : case RTX_MATCH:
1242 : 0 : case RTX_INSN:
1243 : 0 : gcc_unreachable ();
1244 : : }
1245 : :
1246 : 16786975 : if (recurse_p)
1247 : : {
1248 : 7395312 : const char *fmt = GET_RTX_FORMAT (code);
1249 : 21237603 : for (int i = 0; fmt[i]; i++)
1250 : 13931255 : switch (fmt[i])
1251 : : {
1252 : : case 'E':
1253 : 3011488 : for (int j = 0; j < XVECLEN (x, i); j++)
1254 : 2179171 : if (!apply_to_rvalue_1 (&XVECEXP (x, i, j)))
1255 : : return false;
1256 : : break;
1257 : :
1258 : 10177559 : case 'e':
1259 : 10177559 : if (XEXP (x, i) && !apply_to_rvalue_1 (&XEXP (x, i)))
1260 : : return false;
1261 : : break;
1262 : : }
1263 : : }
1264 : 54609724 : else if (newx && !rtx_equal_p (x, newx))
1265 : : {
1266 : : /* All substitutions made by OLD_NUM_CHANGES onwards have been
1267 : : simplified. */
1268 : 3427454 : result_flags = ((result_flags & ~UNSIMPLIFIED)
1269 : : | (old_result_flags & UNSIMPLIFIED));
1270 : :
1271 : 3427454 : if (should_note_simplifications)
1272 : 3302873 : note_simplification (old_num_changes, old_result_flags, x, newx);
1273 : :
1274 : : /* There's no longer any point unsharing the substitutions made
1275 : : for subexpressions, since we'll just copy this one instead. */
1276 : : bool unshare = false;
1277 : 6824119 : for (int i = old_num_changes; i < num_changes; ++i)
1278 : : {
1279 : 3396665 : unshare |= changes[i].unshare;
1280 : 3396665 : changes[i].unshare = false;
1281 : : }
1282 : 3427454 : if (unshare)
1283 : 3246726 : validate_unshare_change (insn, loc, newx, 1);
1284 : : else
1285 : 180728 : validate_change (insn, loc, newx, 1);
1286 : : }
1287 : :
1288 : : return true;
1289 : : }
1290 : :
1291 : : /* Try to process the lvalue expression at *LOC. Return true on success;
1292 : : leave the caller to clean up on failure. */
1293 : :
1294 : : bool
1295 : 25185101 : insn_propagation::apply_to_lvalue_1 (rtx dest)
1296 : : {
1297 : 25185101 : rtx old_dest = dest;
1298 : 25185101 : while (GET_CODE (dest) == SUBREG
1299 : 25241988 : || GET_CODE (dest) == ZERO_EXTRACT
1300 : 25241988 : || GET_CODE (dest) == STRICT_LOW_PART)
1301 : : {
1302 : 56887 : if (GET_CODE (dest) == ZERO_EXTRACT
1303 : 56887 : && (!apply_to_rvalue_1 (&XEXP (dest, 1))
1304 : 859 : || !apply_to_rvalue_1 (&XEXP (dest, 2))))
1305 : 0 : return false;
1306 : 56887 : dest = XEXP (dest, 0);
1307 : : }
1308 : :
1309 : 25185101 : if (MEM_P (dest))
1310 : 4113994 : return apply_to_mem_1 (dest);
1311 : :
1312 : : /* Check whether the substitution is safe in the presence of this lvalue. */
1313 : 21071107 : if (!from
1314 : 21071107 : || dest == old_dest
1315 : 56155 : || !REG_P (dest)
1316 : 21127262 : || !reg_overlap_mentioned_p (dest, from))
1317 : 21071105 : return true;
1318 : :
1319 : 2 : if (SUBREG_P (old_dest)
1320 : 2 : && SUBREG_REG (old_dest) == dest
1321 : 4 : && !read_modify_subreg_p (old_dest))
1322 : : return true;
1323 : :
1324 : 0 : failure_reason = "is part of a read-write destination";
1325 : 0 : return false;
1326 : : }
1327 : :
1328 : : /* Try to process the instruction pattern at *LOC. Return true on success;
1329 : : leave the caller to clean up on failure. */
1330 : :
1331 : : bool
1332 : 27393077 : insn_propagation::apply_to_pattern_1 (rtx *loc)
1333 : : {
1334 : 27393077 : rtx body = *loc;
1335 : 27393077 : switch (GET_CODE (body))
1336 : : {
1337 : 0 : case COND_EXEC:
1338 : 0 : return (apply_to_rvalue_1 (&COND_EXEC_TEST (body))
1339 : 0 : && apply_to_pattern_1 (&COND_EXEC_CODE (body)));
1340 : :
1341 : : case PARALLEL:
1342 : 152283 : for (int i = 0; i < XVECLEN (body, 0); ++i)
1343 : : {
1344 : 124423 : rtx *subloc = &XVECEXP (body, 0, i);
1345 : 124423 : if (GET_CODE (*subloc) == SET)
1346 : : {
1347 : 90461 : if (!apply_to_lvalue_1 (SET_DEST (*subloc)))
1348 : : return false;
1349 : : /* ASM_OPERANDS are shared between SETs in the same PARALLEL.
1350 : : Only process them on the first iteration. */
1351 : 61900 : if ((i == 0 || GET_CODE (SET_SRC (*subloc)) != ASM_OPERANDS)
1352 : 90415 : && !apply_to_rvalue_1 (&SET_SRC (*subloc)))
1353 : : return false;
1354 : : }
1355 : : else
1356 : : {
1357 : 33962 : if (!apply_to_pattern_1 (subloc))
1358 : : return false;
1359 : : }
1360 : : }
1361 : : return true;
1362 : :
1363 : 0 : case ASM_OPERANDS:
1364 : 0 : for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
1365 : 0 : if (!apply_to_rvalue_1 (&ASM_OPERANDS_INPUT (body, i)))
1366 : : return false;
1367 : : return true;
1368 : :
1369 : 33962 : case CLOBBER:
1370 : 33962 : return apply_to_lvalue_1 (XEXP (body, 0));
1371 : :
1372 : 25060678 : case SET:
1373 : 25060678 : return (apply_to_lvalue_1 (SET_DEST (body))
1374 : 25060678 : && apply_to_rvalue_1 (&SET_SRC (body)));
1375 : :
1376 : 2269876 : default:
1377 : : /* All the other possibilities never store and can use a normal
1378 : : rtx walk. This includes:
1379 : :
1380 : : - USE
1381 : : - TRAP_IF
1382 : : - PREFETCH
1383 : : - UNSPEC
1384 : : - UNSPEC_VOLATILE. */
1385 : 2269876 : return apply_to_rvalue_1 (loc);
1386 : : }
1387 : : }
1388 : :
1389 : : /* Apply this insn_propagation object's simplification or substitution
1390 : : to the instruction pattern at LOC. */
1391 : :
1392 : : bool
1393 : 27359115 : insn_propagation::apply_to_pattern (rtx *loc)
1394 : : {
1395 : 27359115 : unsigned int num_changes = num_validated_changes ();
1396 : 27359115 : bool res = apply_to_pattern_1 (loc);
1397 : 27359115 : if (!res)
1398 : 1534480 : cancel_changes (num_changes);
1399 : 27359115 : return res;
1400 : : }
1401 : :
1402 : : /* Apply this insn_propagation object's simplification or substitution
1403 : : to the rvalue expression at LOC. */
1404 : :
1405 : : bool
1406 : 5124523 : insn_propagation::apply_to_rvalue (rtx *loc)
1407 : : {
1408 : 5124523 : unsigned int num_changes = num_validated_changes ();
1409 : 5124523 : bool res = apply_to_rvalue_1 (loc);
1410 : 5124523 : if (!res)
1411 : 17449 : cancel_changes (num_changes);
1412 : 5124523 : return res;
1413 : : }
1414 : :
1415 : : /* Check whether INSN matches a specific alternative of an .md pattern. */
1416 : :
1417 : : bool
1418 : 0 : valid_insn_p (rtx_insn *insn)
1419 : : {
1420 : 0 : recog_memoized (insn);
1421 : 0 : if (INSN_CODE (insn) < 0)
1422 : : return false;
1423 : 0 : extract_insn (insn);
1424 : : /* We don't know whether the insn will be in code that is optimized
1425 : : for size or speed, so consider all enabled alternatives. */
1426 : 0 : if (!constrain_operands (1, get_enabled_alternatives (insn)))
1427 : : return false;
1428 : : return true;
1429 : : }
1430 : :
1431 : : /* Return true if OP is a valid general operand for machine mode MODE.
1432 : : This is either a register reference, a memory reference,
1433 : : or a constant. In the case of a memory reference, the address
1434 : : is checked for general validity for the target machine.
1435 : :
1436 : : Register and memory references must have mode MODE in order to be valid,
1437 : : but some constants have no machine mode and are valid for any mode.
1438 : :
1439 : : If MODE is VOIDmode, OP is checked for validity for whatever mode
1440 : : it has.
1441 : :
1442 : : The main use of this function is as a predicate in match_operand
1443 : : expressions in the machine description. */
1444 : :
1445 : : bool
1446 : 3507088354 : general_operand (rtx op, machine_mode mode)
1447 : : {
1448 : 3507088354 : enum rtx_code code = GET_CODE (op);
1449 : :
1450 : 3507088354 : if (mode == VOIDmode)
1451 : 1143606297 : mode = GET_MODE (op);
1452 : :
1453 : : /* Don't accept CONST_INT or anything similar
1454 : : if the caller wants something floating. */
1455 : 3507088354 : if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1456 : 107816921 : && GET_MODE_CLASS (mode) != MODE_INT
1457 : 2064 : && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1458 : : return false;
1459 : :
1460 : 3507086290 : if (CONST_INT_P (op)
1461 : 152546769 : && mode != VOIDmode
1462 : 3612100110 : && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1463 : : return false;
1464 : :
1465 : 3507086183 : if (CONSTANT_P (op))
1466 : 36348502 : return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
1467 : 7084 : || mode == VOIDmode)
1468 : 189197193 : && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
1469 : 425462942 : && targetm.legitimate_constant_p (mode == VOIDmode
1470 : 47595349 : ? GET_MODE (op)
1471 : : : mode, op));
1472 : :
1473 : : /* Except for certain constants with VOIDmode, already checked for,
1474 : : OP's mode must match MODE if MODE specifies a mode. */
1475 : :
1476 : 3317881906 : if (GET_MODE (op) != mode)
1477 : : return false;
1478 : :
1479 : 3266417682 : if (code == SUBREG)
1480 : : {
1481 : 17420524 : rtx sub = SUBREG_REG (op);
1482 : :
1483 : : #ifdef INSN_SCHEDULING
1484 : : /* On machines that have insn scheduling, we want all memory
1485 : : reference to be explicit, so outlaw paradoxical SUBREGs.
1486 : : However, we must allow them after reload so that they can
1487 : : get cleaned up by cleanup_subreg_operands. */
1488 : 17375432 : if (!reload_completed && MEM_P (sub)
1489 : 17447679 : && paradoxical_subreg_p (op))
1490 : : return false;
1491 : : #endif
1492 : : /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
1493 : : may result in incorrect reference. We should simplify all valid
1494 : : subregs of MEM anyway. But allow this after reload because we
1495 : : might be called from cleanup_subreg_operands.
1496 : :
1497 : : ??? This is a kludge. */
1498 : 17393473 : if (!reload_completed
1499 : 17348381 : && maybe_ne (SUBREG_BYTE (op), 0)
1500 : 19615899 : && MEM_P (sub))
1501 : : return false;
1502 : :
1503 : 17393473 : if (REG_P (sub)
1504 : 16137031 : && REGNO (sub) < FIRST_PSEUDO_REGISTER
1505 : 4082 : && !REG_CAN_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
1506 : 0 : && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
1507 : 0 : && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
1508 : : /* LRA can generate some invalid SUBREGS just for matched
1509 : : operand reload presentation. LRA needs to treat them as
1510 : : valid. */
1511 : 17393473 : && ! LRA_SUBREG_P (op))
1512 : : return false;
1513 : :
1514 : : /* FLOAT_MODE subregs can't be paradoxical. Combine will occasionally
1515 : : create such rtl, and we must reject it. */
1516 : 17393473 : if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
1517 : : /* LRA can use subreg to store a floating point value in an
1518 : : integer mode. Although the floating point and the
1519 : : integer modes need the same number of hard registers, the
1520 : : size of floating point mode can be less than the integer
1521 : : mode. */
1522 : 148620 : && ! lra_in_progress
1523 : 17528806 : && paradoxical_subreg_p (op))
1524 : : return false;
1525 : :
1526 : 17393473 : op = sub;
1527 : 17393473 : code = GET_CODE (op);
1528 : : }
1529 : :
1530 : 3266390631 : if (code == REG)
1531 : 2658833680 : return (REGNO (op) >= FIRST_PSEUDO_REGISTER
1532 : 2658833680 : || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
1533 : :
1534 : 607556951 : if (code == MEM)
1535 : : {
1536 : 535235194 : rtx y = XEXP (op, 0);
1537 : :
1538 : 535235194 : if (! volatile_ok && MEM_VOLATILE_P (op))
1539 : : return false;
1540 : :
1541 : : /* Use the mem's mode, since it will be reloaded thus. LRA can
1542 : : generate move insn with invalid addresses which is made valid
1543 : : and efficiently calculated by LRA through further numerous
1544 : : transformations. */
1545 : 534594769 : if (lra_in_progress
1546 : 581484411 : || memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
1547 : 517611348 : return true;
1548 : : }
1549 : :
1550 : : return false;
1551 : : }
1552 : :
1553 : : /* Return true if OP is a valid memory address for a memory reference
1554 : : of mode MODE.
1555 : :
1556 : : The main use of this function is as a predicate in match_operand
1557 : : expressions in the machine description. */
1558 : :
1559 : : bool
1560 : 83829587 : address_operand (rtx op, machine_mode mode)
1561 : : {
1562 : : /* Wrong mode for an address expr. */
1563 : 83829587 : if (GET_MODE (op) != VOIDmode
1564 : 77656181 : && ! SCALAR_INT_MODE_P (GET_MODE (op)))
1565 : : return false;
1566 : :
1567 : 83236927 : return memory_address_p (mode, op);
1568 : : }
1569 : :
1570 : : /* Return true if OP is a register reference of mode MODE.
1571 : : If MODE is VOIDmode, accept a register in any mode.
1572 : :
1573 : : The main use of this function is as a predicate in match_operand
1574 : : expressions in the machine description. */
1575 : :
1576 : : bool
1577 : 2149863936 : register_operand (rtx op, machine_mode mode)
1578 : : {
1579 : 2149863936 : if (GET_CODE (op) == SUBREG)
1580 : : {
1581 : 6791524 : rtx sub = SUBREG_REG (op);
1582 : :
1583 : : /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
1584 : : because it is guaranteed to be reloaded into one.
1585 : : Just make sure the MEM is valid in itself.
1586 : : (Ideally, (SUBREG (MEM)...) should not exist after reload,
1587 : : but currently it does result from (SUBREG (REG)...) where the
1588 : : reg went on the stack.) */
1589 : 6791524 : if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
1590 : : return false;
1591 : : }
1592 : 2143072412 : else if (!REG_P (op))
1593 : : return false;
1594 : 1617801816 : return general_operand (op, mode);
1595 : : }
1596 : :
1597 : : /* Return true for a register in Pmode; ignore the tested mode. */
1598 : :
1599 : : bool
1600 : 0 : pmode_register_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1601 : : {
1602 : 0 : return register_operand (op, Pmode);
1603 : : }
1604 : :
1605 : : /* Return true if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
1606 : : or a hard register. */
1607 : :
1608 : : bool
1609 : 208895 : scratch_operand (rtx op, machine_mode mode)
1610 : : {
1611 : 208895 : if (GET_MODE (op) != mode && mode != VOIDmode)
1612 : : return false;
1613 : :
1614 : 201222 : return (GET_CODE (op) == SCRATCH
1615 : 201222 : || (REG_P (op)
1616 : 44456 : && (lra_in_progress
1617 : 33026 : || (REGNO (op) < FIRST_PSEUDO_REGISTER
1618 : 31842 : && REGNO_REG_CLASS (REGNO (op)) != NO_REGS))));
1619 : : }
1620 : :
1621 : : /* Return true if OP is a valid immediate operand for mode MODE.
1622 : :
1623 : : The main use of this function is as a predicate in match_operand
1624 : : expressions in the machine description. */
1625 : :
1626 : : bool
1627 : 387623850 : immediate_operand (rtx op, machine_mode mode)
1628 : : {
1629 : : /* Don't accept CONST_INT or anything similar
1630 : : if the caller wants something floating. */
1631 : 387623850 : if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1632 : 71744034 : && GET_MODE_CLASS (mode) != MODE_INT
1633 : 0 : && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1634 : : return false;
1635 : :
1636 : 387623850 : if (CONST_INT_P (op)
1637 : 256900284 : && mode != VOIDmode
1638 : 456508345 : && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1639 : : return false;
1640 : :
1641 : 387449893 : return (CONSTANT_P (op)
1642 : 310412238 : && (GET_MODE (op) == mode || mode == VOIDmode
1643 : 72681533 : || GET_MODE (op) == VOIDmode)
1644 : 308278890 : && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
1645 : 911717372 : && targetm.legitimate_constant_p (mode == VOIDmode
1646 : 219672107 : ? GET_MODE (op)
1647 : : : mode, op));
1648 : : }
1649 : :
1650 : : /* Return true if OP is an operand that is a CONST_INT of mode MODE. */
1651 : :
1652 : : bool
1653 : 27142551 : const_int_operand (rtx op, machine_mode mode)
1654 : : {
1655 : 27142551 : if (!CONST_INT_P (op))
1656 : : return false;
1657 : :
1658 : 21923171 : if (mode != VOIDmode
1659 : 21923171 : && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1660 : : return false;
1661 : :
1662 : : return true;
1663 : : }
1664 : :
1665 : : #if TARGET_SUPPORTS_WIDE_INT
1666 : : /* Return true if OP is an operand that is a CONST_INT or CONST_WIDE_INT
1667 : : of mode MODE. */
1668 : : bool
1669 : 1040952 : const_scalar_int_operand (rtx op, machine_mode mode)
1670 : : {
1671 : 1040952 : if (!CONST_SCALAR_INT_P (op))
1672 : : return false;
1673 : :
1674 : 716660 : if (CONST_INT_P (op))
1675 : 117243 : return const_int_operand (op, mode);
1676 : :
1677 : 599417 : if (mode != VOIDmode)
1678 : : {
1679 : 599417 : scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
1680 : 599417 : int prec = GET_MODE_PRECISION (int_mode);
1681 : 599417 : int bitsize = GET_MODE_BITSIZE (int_mode);
1682 : :
1683 : 599417 : if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
1684 : : return false;
1685 : :
1686 : 599417 : if (prec == bitsize)
1687 : : return true;
1688 : : else
1689 : : {
1690 : : /* Multiword partial int. */
1691 : 4924 : HOST_WIDE_INT x
1692 : 4924 : = CONST_WIDE_INT_ELT (op, CONST_WIDE_INT_NUNITS (op) - 1);
1693 : 4924 : return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
1694 : : }
1695 : : }
1696 : : return true;
1697 : : }
1698 : :
1699 : : /* Return true if OP is an operand that is a constant integer or constant
1700 : : floating-point number of MODE. */
1701 : :
1702 : : bool
1703 : 0 : const_double_operand (rtx op, machine_mode mode)
1704 : : {
1705 : 0 : return (GET_CODE (op) == CONST_DOUBLE)
1706 : 0 : && (GET_MODE (op) == mode || mode == VOIDmode);
1707 : : }
1708 : : #else
1709 : : /* Return true if OP is an operand that is a constant integer or constant
1710 : : floating-point number of MODE. */
1711 : :
1712 : : bool
1713 : : const_double_operand (rtx op, machine_mode mode)
1714 : : {
1715 : : /* Don't accept CONST_INT or anything similar
1716 : : if the caller wants something floating. */
1717 : : if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1718 : : && GET_MODE_CLASS (mode) != MODE_INT
1719 : : && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1720 : : return false;
1721 : :
1722 : : return ((CONST_DOUBLE_P (op) || CONST_INT_P (op))
1723 : : && (mode == VOIDmode || GET_MODE (op) == mode
1724 : : || GET_MODE (op) == VOIDmode));
1725 : : }
1726 : : #endif
1727 : : /* Return true if OP is a general operand that is not an immediate
1728 : : operand of mode MODE. */
1729 : :
1730 : : bool
1731 : 1086071021 : nonimmediate_operand (rtx op, machine_mode mode)
1732 : : {
1733 : 1086071021 : return (general_operand (op, mode) && ! CONSTANT_P (op));
1734 : : }
1735 : :
1736 : : /* Return true if OP is a register reference or
1737 : : immediate value of mode MODE. */
1738 : :
1739 : : bool
1740 : 478671631 : nonmemory_operand (rtx op, machine_mode mode)
1741 : : {
1742 : 478671631 : if (CONSTANT_P (op))
1743 : 16913918 : return immediate_operand (op, mode);
1744 : 461757713 : return register_operand (op, mode);
1745 : : }
1746 : :
1747 : : /* Return true if OP is a valid operand that stands for pushing a
1748 : : value of mode MODE onto the stack.
1749 : :
1750 : : The main use of this function is as a predicate in match_operand
1751 : : expressions in the machine description. */
1752 : :
1753 : : bool
1754 : 609071606 : push_operand (rtx op, machine_mode mode)
1755 : : {
1756 : 609071606 : if (!MEM_P (op))
1757 : : return false;
1758 : :
1759 : 190340039 : if (mode != VOIDmode && GET_MODE (op) != mode)
1760 : : return false;
1761 : :
1762 : 357043174 : poly_int64 rounded_size = GET_MODE_SIZE (mode);
1763 : :
1764 : : #ifdef PUSH_ROUNDING
1765 : 178521587 : rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
1766 : : #endif
1767 : :
1768 : 178521587 : op = XEXP (op, 0);
1769 : :
1770 : 357043174 : if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
1771 : : {
1772 : 153679544 : if (GET_CODE (op) != STACK_PUSH_CODE)
1773 : : return false;
1774 : : }
1775 : : else
1776 : : {
1777 : 24842043 : poly_int64 offset;
1778 : 24842043 : if (GET_CODE (op) != PRE_MODIFY
1779 : 864368 : || GET_CODE (XEXP (op, 1)) != PLUS
1780 : 864368 : || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
1781 : 864368 : || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
1782 : 24842043 : || (STACK_GROWS_DOWNWARD
1783 : 864368 : ? maybe_ne (offset, -rounded_size)
1784 : : : maybe_ne (offset, rounded_size)))
1785 : 575676615 : return false;
1786 : : }
1787 : :
1788 : 33394991 : return XEXP (op, 0) == stack_pointer_rtx;
1789 : : }
1790 : :
1791 : : /* Return true if OP is a valid operand that stands for popping a
1792 : : value of mode MODE off the stack.
1793 : :
1794 : : The main use of this function is as a predicate in match_operand
1795 : : expressions in the machine description. */
1796 : :
1797 : : bool
1798 : 126806885 : pop_operand (rtx op, machine_mode mode)
1799 : : {
1800 : 126806885 : if (!MEM_P (op))
1801 : : return false;
1802 : :
1803 : 36002152 : if (mode != VOIDmode && GET_MODE (op) != mode)
1804 : : return false;
1805 : :
1806 : 36002152 : op = XEXP (op, 0);
1807 : :
1808 : 36002152 : if (GET_CODE (op) != STACK_POP_CODE)
1809 : : return false;
1810 : :
1811 : 1681284 : return XEXP (op, 0) == stack_pointer_rtx;
1812 : : }
1813 : :
1814 : : /* Return true if ADDR is a valid memory address
1815 : : for mode MODE in address space AS. */
1816 : :
1817 : : bool
1818 : 1167177453 : memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr,
1819 : : addr_space_t as, code_helper ch ATTRIBUTE_UNUSED)
1820 : : {
1821 : : #ifdef GO_IF_LEGITIMATE_ADDRESS
1822 : : gcc_assert (ADDR_SPACE_GENERIC_P (as));
1823 : : GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
1824 : : return false;
1825 : :
1826 : : win:
1827 : : return true;
1828 : : #else
1829 : 1167177453 : return targetm.addr_space.legitimate_address_p (mode, addr, 0, as, ch);
1830 : : #endif
1831 : : }
1832 : :
1833 : : /* Return true if OP is a valid memory reference with mode MODE,
1834 : : including a valid address.
1835 : :
1836 : : The main use of this function is as a predicate in match_operand
1837 : : expressions in the machine description. */
1838 : :
1839 : : bool
1840 : 1121184542 : memory_operand (rtx op, machine_mode mode)
1841 : : {
1842 : 1121184542 : rtx inner;
1843 : :
1844 : 1121184542 : if (! reload_completed)
1845 : : /* Note that no SUBREG is a memory operand before end of reload pass,
1846 : : because (SUBREG (MEM...)) forces reloading into a register. */
1847 : 89944924 : return MEM_P (op) && general_operand (op, mode);
1848 : :
1849 : 1031239618 : if (mode != VOIDmode && GET_MODE (op) != mode)
1850 : : return false;
1851 : :
1852 : 757575679 : inner = op;
1853 : 757575679 : if (GET_CODE (inner) == SUBREG)
1854 : 8675 : inner = SUBREG_REG (inner);
1855 : :
1856 : 757575679 : return (MEM_P (inner) && general_operand (op, mode));
1857 : : }
1858 : :
1859 : : /* Return true if OP is a valid indirect memory reference with mode MODE;
1860 : : that is, a memory reference whose address is a general_operand. */
1861 : :
1862 : : bool
1863 : 0 : indirect_operand (rtx op, machine_mode mode)
1864 : : {
1865 : : /* Before reload, a SUBREG isn't in memory (see memory_operand, above). */
1866 : 0 : if (! reload_completed
1867 : 0 : && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
1868 : : {
1869 : 0 : if (mode != VOIDmode && GET_MODE (op) != mode)
1870 : : return false;
1871 : :
1872 : : /* The only way that we can have a general_operand as the resulting
1873 : : address is if OFFSET is zero and the address already is an operand
1874 : : or if the address is (plus Y (const_int -OFFSET)) and Y is an
1875 : : operand. */
1876 : 0 : poly_int64 offset;
1877 : 0 : rtx addr = strip_offset (XEXP (SUBREG_REG (op), 0), &offset);
1878 : 0 : return (known_eq (offset + SUBREG_BYTE (op), 0)
1879 : 0 : && general_operand (addr, Pmode));
1880 : : }
1881 : :
1882 : 0 : return (MEM_P (op)
1883 : 0 : && memory_operand (op, mode)
1884 : 0 : && general_operand (XEXP (op, 0), Pmode));
1885 : : }
1886 : :
1887 : : /* Return true if this is an ordered comparison operator (not including
1888 : : ORDERED and UNORDERED). */
1889 : :
1890 : : bool
1891 : 24652895 : ordered_comparison_operator (rtx op, machine_mode mode)
1892 : : {
1893 : 24652895 : if (mode != VOIDmode && GET_MODE (op) != mode)
1894 : : return false;
1895 : 24652895 : switch (GET_CODE (op))
1896 : : {
1897 : : case EQ:
1898 : : case NE:
1899 : : case LT:
1900 : : case LTU:
1901 : : case LE:
1902 : : case LEU:
1903 : : case GT:
1904 : : case GTU:
1905 : : case GE:
1906 : : case GEU:
1907 : : return true;
1908 : : default:
1909 : : return false;
1910 : : }
1911 : : }
1912 : :
1913 : : /* Return true if this is a comparison operator. This allows the use of
1914 : : MATCH_OPERATOR to recognize all the branch insns. */
1915 : :
1916 : : bool
1917 : 58465018 : comparison_operator (rtx op, machine_mode mode)
1918 : : {
1919 : 1776460 : return ((mode == VOIDmode || GET_MODE (op) == mode)
1920 : 59995416 : && COMPARISON_P (op));
1921 : : }
1922 : :
1923 : : /* If BODY is an insn body that uses ASM_OPERANDS, return it. */
1924 : :
1925 : : rtx
1926 : 1544200096 : extract_asm_operands (rtx body)
1927 : : {
1928 : 1544200096 : rtx tmp;
1929 : 1544200096 : switch (GET_CODE (body))
1930 : : {
1931 : : case ASM_OPERANDS:
1932 : : return body;
1933 : :
1934 : 1200124762 : case SET:
1935 : : /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */
1936 : 1200124762 : tmp = SET_SRC (body);
1937 : 1200124762 : if (GET_CODE (tmp) == ASM_OPERANDS)
1938 : : return tmp;
1939 : : break;
1940 : :
1941 : 271001018 : case PARALLEL:
1942 : 271001018 : tmp = XVECEXP (body, 0, 0);
1943 : 271001018 : if (GET_CODE (tmp) == ASM_OPERANDS)
1944 : : return tmp;
1945 : 269058025 : if (GET_CODE (tmp) == SET)
1946 : : {
1947 : 265586323 : tmp = SET_SRC (tmp);
1948 : 265586323 : if (GET_CODE (tmp) == ASM_OPERANDS)
1949 : : return tmp;
1950 : : }
1951 : : break;
1952 : :
1953 : : default:
1954 : : break;
1955 : : }
1956 : 1539237586 : return NULL;
1957 : : }
1958 : :
1959 : : /* If BODY is an insn body that uses ASM_OPERANDS,
1960 : : return the number of operands (both input and output) in the insn.
1961 : : If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
1962 : : return 0.
1963 : : Otherwise return -1. */
1964 : :
1965 : : int
1966 : 1117908824 : asm_noperands (const_rtx body)
1967 : : {
1968 : 1117908824 : rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
1969 : 1117908824 : int i, n_sets = 0;
1970 : :
1971 : 1117908824 : if (asm_op == NULL)
1972 : : {
1973 : 1113806972 : if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
1974 : 188838512 : && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
1975 : : {
1976 : : /* body is [(asm_input ...) (clobber (reg ...))...]. */
1977 : 45765 : for (i = XVECLEN (body, 0) - 1; i > 0; i--)
1978 : 30510 : if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
1979 : : return -1;
1980 : : return 0;
1981 : : }
1982 : : return -1;
1983 : : }
1984 : :
1985 : 4101852 : if (GET_CODE (body) == SET)
1986 : : n_sets = 1;
1987 : 4081218 : else if (GET_CODE (body) == PARALLEL)
1988 : : {
1989 : 4071296 : if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
1990 : : {
1991 : : /* Multiple output operands, or 1 output plus some clobbers:
1992 : : body is
1993 : : [(set OUTPUT (asm_operands ...))...
1994 : : (use (reg ...))...
1995 : : (clobber (reg ...))...]. */
1996 : : /* Count backwards through USEs and CLOBBERs to determine
1997 : : number of SETs. */
1998 : 5212718 : for (i = XVECLEN (body, 0); i > 0; i--)
1999 : : {
2000 : 5212718 : if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
2001 : : break;
2002 : 2768205 : if (GET_CODE (XVECEXP (body, 0, i - 1)) != USE
2003 : 2768205 : && GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
2004 : : return -1;
2005 : : }
2006 : :
2007 : : /* N_SETS is now number of output operands. */
2008 : 9754314 : n_sets = i;
2009 : :
2010 : : /* Verify that all the SETs we have
2011 : : came from a single original asm_operands insn
2012 : : (so that invalid combinations are blocked). */
2013 : 9754314 : for (i = 0; i < n_sets; i++)
2014 : : {
2015 : 7375540 : rtx elt = XVECEXP (body, 0, i);
2016 : 7375540 : if (GET_CODE (elt) != SET)
2017 : : return -1;
2018 : 7369548 : if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
2019 : : return -1;
2020 : : /* If these ASM_OPERANDS rtx's came from different original insns
2021 : : then they aren't allowed together. */
2022 : 7351327 : if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
2023 : 7351327 : != ASM_OPERANDS_INPUT_VEC (asm_op))
2024 : : return -1;
2025 : : }
2026 : : }
2027 : : else
2028 : : {
2029 : : /* 0 outputs, but some clobbers:
2030 : : body is [(asm_operands ...)
2031 : : (use (reg ...))...
2032 : : (clobber (reg ...))...]. */
2033 : : /* Make sure all the other parallel things really are clobbers. */
2034 : 5066151 : for (i = XVECLEN (body, 0) - 1; i > 0; i--)
2035 : 3441640 : if (GET_CODE (XVECEXP (body, 0, i)) != USE
2036 : 3441640 : && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
2037 : : return -1;
2038 : : }
2039 : : }
2040 : :
2041 : 4033841 : return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
2042 : 4033841 : + ASM_OPERANDS_LABEL_LENGTH (asm_op) + n_sets);
2043 : : }
2044 : :
2045 : : /* Assuming BODY is an insn body that uses ASM_OPERANDS,
2046 : : copy its operands (both input and output) into the vector OPERANDS,
2047 : : the locations of the operands within the insn into the vector OPERAND_LOCS,
2048 : : and the constraints for the operands into CONSTRAINTS.
2049 : : Write the modes of the operands into MODES.
2050 : : Write the location info into LOC.
2051 : : Return the assembler-template.
2052 : : If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
2053 : : return the basic assembly string.
2054 : :
2055 : : If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
2056 : : we don't store that info. */
2057 : :
2058 : : const char *
2059 : 1804827 : decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
2060 : : const char **constraints, machine_mode *modes,
2061 : : location_t *loc)
2062 : : {
2063 : 1804827 : int nbase = 0, n, i;
2064 : 1804827 : rtx asmop;
2065 : :
2066 : 1804827 : switch (GET_CODE (body))
2067 : : {
2068 : : case ASM_OPERANDS:
2069 : : /* Zero output asm: BODY is (asm_operands ...). */
2070 : : asmop = body;
2071 : : break;
2072 : :
2073 : 10140 : case SET:
2074 : : /* Single output asm: BODY is (set OUTPUT (asm_operands ...)). */
2075 : 10140 : asmop = SET_SRC (body);
2076 : :
2077 : : /* The output is in the SET.
2078 : : Its constraint is in the ASM_OPERANDS itself. */
2079 : 10140 : if (operands)
2080 : 10030 : operands[0] = SET_DEST (body);
2081 : 10140 : if (operand_locs)
2082 : 430 : operand_locs[0] = &SET_DEST (body);
2083 : 10140 : if (constraints)
2084 : 10030 : constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
2085 : 10140 : if (modes)
2086 : 430 : modes[0] = GET_MODE (SET_DEST (body));
2087 : : nbase = 1;
2088 : : break;
2089 : :
2090 : 1790519 : case PARALLEL:
2091 : 1790519 : {
2092 : 1790519 : int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */
2093 : :
2094 : 1790519 : asmop = XVECEXP (body, 0, 0);
2095 : 1790519 : if (GET_CODE (asmop) == SET)
2096 : : {
2097 : 898035 : asmop = SET_SRC (asmop);
2098 : :
2099 : : /* At least one output, plus some CLOBBERs. The outputs are in
2100 : : the SETs. Their constraints are in the ASM_OPERANDS itself. */
2101 : 3405270 : for (i = 0; i < nparallel; i++)
2102 : : {
2103 : 3379833 : if (GET_CODE (XVECEXP (body, 0, i)) == USE
2104 : 3379833 : || GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
2105 : : break; /* Past last SET */
2106 : 2507235 : gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
2107 : 2507235 : if (operands)
2108 : 2309747 : operands[i] = SET_DEST (XVECEXP (body, 0, i));
2109 : 2507235 : if (operand_locs)
2110 : 1032004 : operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
2111 : 2507235 : if (constraints)
2112 : 2323953 : constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
2113 : 2507235 : if (modes)
2114 : 1032004 : modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
2115 : : }
2116 : : nbase = i;
2117 : : }
2118 : 892484 : else if (GET_CODE (asmop) == ASM_INPUT)
2119 : : {
2120 : 8206 : if (loc)
2121 : 0 : *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
2122 : 8206 : return XSTR (asmop, 0);
2123 : : }
2124 : : break;
2125 : : }
2126 : :
2127 : 0 : default:
2128 : 0 : gcc_unreachable ();
2129 : : }
2130 : :
2131 : 1796621 : n = ASM_OPERANDS_INPUT_LENGTH (asmop);
2132 : 3292417 : for (i = 0; i < n; i++)
2133 : : {
2134 : 1495796 : if (operand_locs)
2135 : 683950 : operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
2136 : 1495796 : if (operands)
2137 : 1356793 : operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
2138 : 1495796 : if (constraints)
2139 : 1374197 : constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
2140 : 1495796 : if (modes)
2141 : 683950 : modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
2142 : : }
2143 : 1796621 : nbase += n;
2144 : :
2145 : 1796621 : n = ASM_OPERANDS_LABEL_LENGTH (asmop);
2146 : 1811196 : for (i = 0; i < n; i++)
2147 : : {
2148 : 14575 : if (operand_locs)
2149 : 8322 : operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
2150 : 14575 : if (operands)
2151 : 13096 : operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
2152 : 14575 : if (constraints)
2153 : 13165 : constraints[nbase + i] = "";
2154 : 14575 : if (modes)
2155 : 8322 : modes[nbase + i] = Pmode;
2156 : : }
2157 : :
2158 : 1796621 : if (loc)
2159 : 112114 : *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
2160 : :
2161 : 1796621 : return ASM_OPERANDS_TEMPLATE (asmop);
2162 : : }
2163 : :
2164 : : /* Parse inline assembly string STRING and determine which operands are
2165 : : referenced by % markers. For the first NOPERANDS operands, set USED[I]
2166 : : to true if operand I is referenced.
2167 : :
2168 : : This is intended to distinguish barrier-like asms such as:
2169 : :
2170 : : asm ("" : "=m" (...));
2171 : :
2172 : : from real references such as:
2173 : :
2174 : : asm ("sw\t$0, %0" : "=m" (...)); */
2175 : :
2176 : : void
2177 : 0 : get_referenced_operands (const char *string, bool *used,
2178 : : unsigned int noperands)
2179 : : {
2180 : 0 : memset (used, 0, sizeof (bool) * noperands);
2181 : 0 : const char *p = string;
2182 : 0 : while (*p)
2183 : 0 : switch (*p)
2184 : : {
2185 : 0 : case '%':
2186 : 0 : p += 1;
2187 : : /* A letter followed by a digit indicates an operand number. */
2188 : 0 : if (ISALPHA (p[0]) && ISDIGIT (p[1]))
2189 : 0 : p += 1;
2190 : 0 : if (ISDIGIT (*p))
2191 : : {
2192 : 0 : char *endptr;
2193 : 0 : unsigned long opnum = strtoul (p, &endptr, 10);
2194 : 0 : if (endptr != p && opnum < noperands)
2195 : 0 : used[opnum] = true;
2196 : 0 : p = endptr;
2197 : : }
2198 : : else
2199 : 0 : p += 1;
2200 : : break;
2201 : :
2202 : 0 : default:
2203 : 0 : p++;
2204 : 0 : break;
2205 : : }
2206 : 0 : }
2207 : :
2208 : : /* Check if an asm_operand matches its constraints.
2209 : : Return > 0 if ok, = 0 if bad, < 0 if inconclusive. */
2210 : :
2211 : : int
2212 : 2322303 : asm_operand_ok (rtx op, const char *constraint, const char **constraints)
2213 : : {
2214 : 2322303 : int result = 0;
2215 : 2322303 : bool incdec_ok = false;
2216 : :
2217 : : /* Use constrain_operands after reload. */
2218 : 2322303 : gcc_assert (!reload_completed);
2219 : :
2220 : : /* Empty constraint string is the same as "X,...,X", i.e. X for as
2221 : : many alternatives as required to match the other operands. */
2222 : 2322303 : if (*constraint == '\0')
2223 : 1324 : result = 1;
2224 : :
2225 : 6418957 : while (*constraint)
2226 : : {
2227 : 4096656 : enum constraint_num cn;
2228 : 4096656 : char c = *constraint;
2229 : 4096656 : int len;
2230 : 4096656 : switch (c)
2231 : : {
2232 : 2890 : case ',':
2233 : 2890 : constraint++;
2234 : 2890 : continue;
2235 : :
2236 : 415836 : case '0': case '1': case '2': case '3': case '4':
2237 : 415836 : case '5': case '6': case '7': case '8': case '9':
2238 : : /* If caller provided constraints pointer, look up
2239 : : the matching constraint. Otherwise, our caller should have
2240 : : given us the proper matching constraint, but we can't
2241 : : actually fail the check if they didn't. Indicate that
2242 : : results are inconclusive. */
2243 : 415836 : if (constraints)
2244 : : {
2245 : 415633 : char *end;
2246 : 415633 : unsigned long match;
2247 : :
2248 : 415633 : match = strtoul (constraint, &end, 10);
2249 : 415633 : if (!result)
2250 : 415497 : result = asm_operand_ok (op, constraints[match], NULL);
2251 : 415633 : constraint = (const char *) end;
2252 : : }
2253 : : else
2254 : : {
2255 : 227 : do
2256 : 227 : constraint++;
2257 : 227 : while (ISDIGIT (*constraint));
2258 : 203 : if (! result)
2259 : 176 : result = -1;
2260 : : }
2261 : 415836 : continue;
2262 : :
2263 : : /* The rest of the compiler assumes that reloading the address
2264 : : of a MEM into a register will make it fit an 'o' constraint.
2265 : : That is, if it sees a MEM operand for an 'o' constraint,
2266 : : it assumes that (mem (base-reg)) will fit.
2267 : :
2268 : : That assumption fails on targets that don't have offsettable
2269 : : addresses at all. We therefore need to treat 'o' asm
2270 : : constraints as a special case and only accept operands that
2271 : : are already offsettable, thus proving that at least one
2272 : : offsettable address exists. */
2273 : 27 : case 'o': /* offsettable */
2274 : 27 : if (offsettable_nonstrict_memref_p (op))
2275 : 1497853 : result = 1;
2276 : : break;
2277 : :
2278 : 36378 : case 'g':
2279 : 36378 : if (general_operand (op, VOIDmode))
2280 : 1497853 : result = 1;
2281 : : break;
2282 : :
2283 : : case '<':
2284 : : case '>':
2285 : : /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
2286 : : to exist, excepting those that expand_call created. Further,
2287 : : on some machines which do not have generalized auto inc/dec,
2288 : : an inc/dec is not a memory_operand.
2289 : :
2290 : : Match any memory and hope things are resolved after reload. */
2291 : 3641525 : incdec_ok = true;
2292 : : /* FALLTHRU */
2293 : 3641525 : default:
2294 : 3641525 : cn = lookup_constraint (constraint);
2295 : 3641525 : rtx mem = NULL;
2296 : 3641525 : switch (get_constraint_type (cn))
2297 : : {
2298 : 3592360 : case CT_REGISTER:
2299 : 3592360 : if (!result
2300 : 1827249 : && reg_class_for_constraint (cn) != NO_REGS
2301 : 1827249 : && GET_MODE (op) != BLKmode
2302 : 5419572 : && register_operand (op, VOIDmode))
2303 : : result = 1;
2304 : : break;
2305 : :
2306 : 4 : case CT_CONST_INT:
2307 : 4 : if (!result
2308 : 4 : && CONST_INT_P (op)
2309 : 6 : && insn_const_int_ok_for_constraint (INTVAL (op), cn))
2310 : : result = 1;
2311 : : break;
2312 : :
2313 : 41187 : case CT_MEMORY:
2314 : 41187 : case CT_RELAXED_MEMORY:
2315 : 41187 : mem = op;
2316 : : /* Fall through. */
2317 : 41187 : case CT_SPECIAL_MEMORY:
2318 : : /* Every memory operand can be reloaded to fit. */
2319 : 41187 : if (!mem)
2320 : 0 : mem = extract_mem_from_operand (op);
2321 : 41187 : result = result || memory_operand (mem, VOIDmode);
2322 : 41187 : break;
2323 : :
2324 : 79 : case CT_ADDRESS:
2325 : : /* Every address operand can be reloaded to fit. */
2326 : 79 : result = result || address_operand (op, VOIDmode);
2327 : 79 : break;
2328 : :
2329 : 7895 : case CT_FIXED_FORM:
2330 : 7895 : result = result || constraint_satisfied_p (op, cn);
2331 : 7895 : break;
2332 : : }
2333 : : break;
2334 : 418726 : }
2335 : 3677930 : len = CONSTRAINT_LEN (c, constraint);
2336 : 3678506 : do
2337 : 3678506 : constraint++;
2338 : 7356436 : while (--len && *constraint && *constraint != ',');
2339 : 3677930 : if (len)
2340 : : return 0;
2341 : : }
2342 : :
2343 : : /* For operands without < or > constraints reject side-effects. */
2344 : : if (AUTO_INC_DEC && !incdec_ok && result && MEM_P (op))
2345 : : switch (GET_CODE (XEXP (op, 0)))
2346 : : {
2347 : : case PRE_INC:
2348 : : case POST_INC:
2349 : : case PRE_DEC:
2350 : : case POST_DEC:
2351 : : case PRE_MODIFY:
2352 : : case POST_MODIFY:
2353 : : return 0;
2354 : : default:
2355 : : break;
2356 : : }
2357 : :
2358 : : return result;
2359 : : }
2360 : :
2361 : : /* Given an rtx *P, if it is a sum containing an integer constant term,
2362 : : return the location (type rtx *) of the pointer to that constant term.
2363 : : Otherwise, return a null pointer. */
2364 : :
2365 : : rtx *
2366 : 39916491 : find_constant_term_loc (rtx *p)
2367 : : {
2368 : 39916491 : rtx *tem;
2369 : 39916491 : enum rtx_code code = GET_CODE (*p);
2370 : :
2371 : : /* If *P IS such a constant term, P is its location. */
2372 : :
2373 : 39916491 : if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
2374 : 27969988 : || code == CONST)
2375 : : return p;
2376 : :
2377 : : /* Otherwise, if not a sum, it has no constant term. */
2378 : :
2379 : 27930525 : if (GET_CODE (*p) != PLUS)
2380 : : return 0;
2381 : :
2382 : : /* If one of the summands is constant, return its location. */
2383 : :
2384 : 13319957 : if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
2385 : 0 : && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
2386 : : return p;
2387 : :
2388 : : /* Otherwise, check each summand for containing a constant term. */
2389 : :
2390 : 13319957 : if (XEXP (*p, 0) != 0)
2391 : : {
2392 : 13319957 : tem = find_constant_term_loc (&XEXP (*p, 0));
2393 : 13319957 : if (tem != 0)
2394 : : return tem;
2395 : : }
2396 : :
2397 : 13319957 : if (XEXP (*p, 1) != 0)
2398 : : {
2399 : 13319957 : tem = find_constant_term_loc (&XEXP (*p, 1));
2400 : 13319957 : if (tem != 0)
2401 : : return tem;
2402 : : }
2403 : :
2404 : : return 0;
2405 : : }
2406 : :
2407 : : /* Return true if OP is a memory reference whose address contains
2408 : : no side effects and remains valid after the addition of a positive
2409 : : integer less than the size of the object being referenced.
2410 : :
2411 : : We assume that the original address is valid and do not check it.
2412 : :
2413 : : This uses strict_memory_address_p as a subroutine, so
2414 : : don't use it before reload. */
2415 : :
2416 : : bool
2417 : 5432059 : offsettable_memref_p (rtx op)
2418 : : {
2419 : 5432059 : return ((MEM_P (op))
2420 : 10861468 : && offsettable_address_addr_space_p (1, GET_MODE (op), XEXP (op, 0),
2421 : 5429409 : MEM_ADDR_SPACE (op)));
2422 : : }
2423 : :
2424 : : /* Similar, but don't require a strictly valid mem ref:
2425 : : consider pseudo-regs valid as index or base regs. */
2426 : :
2427 : : bool
2428 : 12422280 : offsettable_nonstrict_memref_p (rtx op)
2429 : : {
2430 : 12422280 : return ((MEM_P (op))
2431 : 24844535 : && offsettable_address_addr_space_p (0, GET_MODE (op), XEXP (op, 0),
2432 : 12422255 : MEM_ADDR_SPACE (op)));
2433 : : }
2434 : :
2435 : : /* Return true if Y is a memory address which contains no side effects
2436 : : and would remain valid for address space AS after the addition of
2437 : : a positive integer less than the size of that mode.
2438 : :
2439 : : We assume that the original address is valid and do not check it.
2440 : : We do check that it is valid for narrower modes.
2441 : :
2442 : : If STRICTP is nonzero, we require a strictly valid address,
2443 : : for the sake of use in reload.cc. */
2444 : :
2445 : : bool
2446 : 17851664 : offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
2447 : : addr_space_t as)
2448 : : {
2449 : 17851664 : enum rtx_code ycode = GET_CODE (y);
2450 : 17851664 : rtx z;
2451 : 17851664 : rtx y1 = y;
2452 : 17851664 : rtx *y2;
2453 : 35703328 : bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
2454 : 17851664 : (strictp ? strict_memory_address_addr_space_p
2455 : : : memory_address_addr_space_p);
2456 : 35703328 : poly_int64 mode_sz = GET_MODE_SIZE (mode);
2457 : :
2458 : 17851664 : if (CONSTANT_ADDRESS_P (y))
2459 : : return true;
2460 : :
2461 : : /* Adjusting an offsettable address involves changing to a narrower mode.
2462 : : Make sure that's OK. */
2463 : :
2464 : 15207446 : if (mode_dependent_address_p (y, as))
2465 : : return false;
2466 : :
2467 : 15023962 : machine_mode address_mode = GET_MODE (y);
2468 : 15023962 : if (address_mode == VOIDmode)
2469 : 0 : address_mode = targetm.addr_space.address_mode (as);
2470 : : #ifdef POINTERS_EXTEND_UNSIGNED
2471 : 15023962 : machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
2472 : : #endif
2473 : :
2474 : : /* ??? How much offset does an offsettable BLKmode reference need?
2475 : : Clearly that depends on the situation in which it's being used.
2476 : : However, the current situation in which we test 0xffffffff is
2477 : : less than ideal. Caveat user. */
2478 : 15023962 : if (known_eq (mode_sz, 0))
2479 : 0 : mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
2480 : :
2481 : : /* If the expression contains a constant term,
2482 : : see if it remains valid when max possible offset is added. */
2483 : :
2484 : 15023962 : if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
2485 : : {
2486 : 11985966 : bool good;
2487 : :
2488 : 11985966 : y1 = *y2;
2489 : 11985966 : *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
2490 : : /* Use QImode because an odd displacement may be automatically invalid
2491 : : for any wider mode. But it should be valid for a single byte. */
2492 : 11985966 : good = (*addressp) (QImode, y, as, ERROR_MARK);
2493 : :
2494 : : /* In any case, restore old contents of memory. */
2495 : 11985966 : *y2 = y1;
2496 : 11985966 : return good;
2497 : : }
2498 : :
2499 : 3037996 : if (GET_RTX_CLASS (ycode) == RTX_AUTOINC)
2500 : : return false;
2501 : :
2502 : : /* The offset added here is chosen as the maximum offset that
2503 : : any instruction could need to add when operating on something
2504 : : of the specified mode. We assume that if Y and Y+c are
2505 : : valid addresses then so is Y+d for all 0<d<c. adjust_address will
2506 : : go inside a LO_SUM here, so we do so as well. */
2507 : 3037996 : if (GET_CODE (y) == LO_SUM
2508 : 0 : && mode != BLKmode
2509 : 3037996 : && known_le (mode_sz, GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT))
2510 : 0 : z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
2511 : : plus_constant (address_mode, XEXP (y, 1),
2512 : : mode_sz - 1));
2513 : : #ifdef POINTERS_EXTEND_UNSIGNED
2514 : : /* Likewise for a ZERO_EXTEND from pointer_mode. */
2515 : 3037996 : else if (POINTERS_EXTEND_UNSIGNED > 0
2516 : 3037996 : && GET_CODE (y) == ZERO_EXTEND
2517 : 12 : && GET_MODE (XEXP (y, 0)) == pointer_mode)
2518 : 7 : z = gen_rtx_ZERO_EXTEND (address_mode,
2519 : : plus_constant (pointer_mode, XEXP (y, 0),
2520 : : mode_sz - 1));
2521 : : #endif
2522 : : else
2523 : 3037989 : z = plus_constant (address_mode, y, mode_sz - 1);
2524 : :
2525 : : /* Use QImode because an odd displacement may be automatically invalid
2526 : : for any wider mode. But it should be valid for a single byte. */
2527 : 3037996 : return (*addressp) (QImode, z, as, ERROR_MARK);
2528 : : }
2529 : :
2530 : : /* Return true if ADDR is an address-expression whose effect depends
2531 : : on the mode of the memory reference it is used in.
2532 : :
2533 : : ADDRSPACE is the address space associated with the address.
2534 : :
2535 : : Autoincrement addressing is a typical example of mode-dependence
2536 : : because the amount of the increment depends on the mode. */
2537 : :
2538 : : bool
2539 : 39117090 : mode_dependent_address_p (rtx addr, addr_space_t addrspace)
2540 : : {
2541 : : /* Auto-increment addressing with anything other than post_modify
2542 : : or pre_modify always introduces a mode dependency. Catch such
2543 : : cases now instead of deferring to the target. */
2544 : 39117090 : if (GET_CODE (addr) == PRE_INC
2545 : 39117090 : || GET_CODE (addr) == POST_INC
2546 : 39117084 : || GET_CODE (addr) == PRE_DEC
2547 : 35364501 : || GET_CODE (addr) == POST_DEC)
2548 : : return true;
2549 : :
2550 : 35364501 : return targetm.mode_dependent_address_p (addr, addrspace);
2551 : : }
2552 : :
2553 : : /* Return true if boolean attribute ATTR is supported. */
2554 : :
2555 : : static bool
2556 : 1488979680 : have_bool_attr (bool_attr attr)
2557 : : {
2558 : 1488979680 : switch (attr)
2559 : : {
2560 : : case BA_ENABLED:
2561 : : return HAVE_ATTR_enabled;
2562 : : case BA_PREFERRED_FOR_SIZE:
2563 : : return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size;
2564 : : case BA_PREFERRED_FOR_SPEED:
2565 : : return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed;
2566 : : }
2567 : 0 : gcc_unreachable ();
2568 : : }
2569 : :
2570 : : /* Return the value of ATTR for instruction INSN. */
2571 : :
2572 : : static bool
2573 : 1515176221 : get_bool_attr (rtx_insn *insn, bool_attr attr)
2574 : : {
2575 : 1515176221 : switch (attr)
2576 : : {
2577 : 650009345 : case BA_ENABLED:
2578 : 650009345 : return get_attr_enabled (insn);
2579 : 303380245 : case BA_PREFERRED_FOR_SIZE:
2580 : 303380245 : return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
2581 : 561786631 : case BA_PREFERRED_FOR_SPEED:
2582 : 561786631 : return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn);
2583 : : }
2584 : 0 : gcc_unreachable ();
2585 : : }
2586 : :
2587 : : /* Like get_bool_attr_mask, but don't use the cache. */
2588 : :
2589 : : static alternative_mask
2590 : 91416464 : get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr)
2591 : : {
2592 : : /* Temporarily install enough information for get_attr_<foo> to assume
2593 : : that the insn operands are already cached. As above, the attribute
2594 : : mustn't depend on the values of operands, so we don't provide their
2595 : : real values here. */
2596 : 91416464 : rtx_insn *old_insn = recog_data.insn;
2597 : 91416464 : int old_alternative = which_alternative;
2598 : :
2599 : 91416464 : recog_data.insn = insn;
2600 : 91416464 : alternative_mask mask = ALL_ALTERNATIVES;
2601 : 91416464 : int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
2602 : 1606592685 : for (int i = 0; i < n_alternatives; i++)
2603 : : {
2604 : 1515176221 : which_alternative = i;
2605 : 1515176221 : if (!get_bool_attr (insn, attr))
2606 : 231679806 : mask &= ~ALTERNATIVE_BIT (i);
2607 : : }
2608 : :
2609 : 91416464 : recog_data.insn = old_insn;
2610 : 91416464 : which_alternative = old_alternative;
2611 : 91416464 : return mask;
2612 : : }
2613 : :
2614 : : /* Return the mask of operand alternatives that are allowed for INSN
2615 : : by boolean attribute ATTR. This mask depends only on INSN and on
2616 : : the current target; it does not depend on things like the values of
2617 : : operands. */
2618 : :
2619 : : static alternative_mask
2620 : 1491254018 : get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
2621 : : {
2622 : : /* Quick exit for asms and for targets that don't use these attributes. */
2623 : 1491254018 : int code = INSN_CODE (insn);
2624 : 1491254018 : if (code < 0 || !have_bool_attr (attr))
2625 : : return ALL_ALTERNATIVES;
2626 : :
2627 : : /* Calling get_attr_<foo> can be expensive, so cache the mask
2628 : : for speed. */
2629 : 1488979680 : if (!this_target_recog->x_bool_attr_masks[code][attr])
2630 : 12385652 : this_target_recog->x_bool_attr_masks[code][attr]
2631 : 12385652 : = get_bool_attr_mask_uncached (insn, attr);
2632 : 1488979680 : return this_target_recog->x_bool_attr_masks[code][attr];
2633 : : }
2634 : :
2635 : : /* Return the set of alternatives of INSN that are allowed by the current
2636 : : target. */
2637 : :
2638 : : alternative_mask
2639 : 1061194580 : get_enabled_alternatives (rtx_insn *insn)
2640 : : {
2641 : 1061194580 : return get_bool_attr_mask (insn, BA_ENABLED);
2642 : : }
2643 : :
2644 : : /* Return the set of alternatives of INSN that are allowed by the current
2645 : : target and are preferred for the current size/speed optimization
2646 : : choice. */
2647 : :
2648 : : alternative_mask
2649 : 429982463 : get_preferred_alternatives (rtx_insn *insn)
2650 : : {
2651 : 429982463 : if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
2652 : 379966385 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
2653 : : else
2654 : 50016078 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
2655 : : }
2656 : :
2657 : : /* Return the set of alternatives of INSN that are allowed by the current
2658 : : target and are preferred for the size/speed optimization choice
2659 : : associated with BB. Passing a separate BB is useful if INSN has not
2660 : : been emitted yet or if we are considering moving it to a different
2661 : : block. */
2662 : :
2663 : : alternative_mask
2664 : 76975 : get_preferred_alternatives (rtx_insn *insn, basic_block bb)
2665 : : {
2666 : 76975 : if (optimize_bb_for_speed_p (bb))
2667 : 73550 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
2668 : : else
2669 : 3425 : return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
2670 : : }
2671 : :
2672 : : /* Assert that the cached boolean attributes for INSN are still accurate.
2673 : : The backend is required to define these attributes in a way that only
2674 : : depends on the current target (rather than operands, compiler phase,
2675 : : etc.). */
2676 : :
2677 : : bool
2678 : 32144391 : check_bool_attrs (rtx_insn *insn)
2679 : : {
2680 : 32144391 : int code = INSN_CODE (insn);
2681 : 32144391 : if (code >= 0)
2682 : 128577564 : for (int i = 0; i <= BA_LAST; ++i)
2683 : : {
2684 : 96433173 : enum bool_attr attr = (enum bool_attr) i;
2685 : 96433173 : if (this_target_recog->x_bool_attr_masks[code][attr])
2686 : 79030812 : gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
2687 : : == get_bool_attr_mask_uncached (insn, attr));
2688 : : }
2689 : 32144391 : return true;
2690 : : }
2691 : :
2692 : : /* Like extract_insn, but save insn extracted and don't extract again, when
2693 : : called again for the same insn expecting that recog_data still contain the
2694 : : valid information. This is used primary by gen_attr infrastructure that
2695 : : often does extract insn again and again. */
2696 : : void
2697 : 9103734959 : extract_insn_cached (rtx_insn *insn)
2698 : : {
2699 : 9103734959 : if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
2700 : : return;
2701 : 677371965 : extract_insn (insn);
2702 : 677371965 : recog_data.insn = insn;
2703 : : }
2704 : :
2705 : : /* Do uncached extract_insn, constrain_operands and complain about failures.
2706 : : This should be used when extracting a pre-existing constrained instruction
2707 : : if the caller wants to know which alternative was chosen. */
2708 : : void
2709 : 245802100 : extract_constrain_insn (rtx_insn *insn)
2710 : : {
2711 : 245802100 : extract_insn (insn);
2712 : 245802100 : if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
2713 : 0 : fatal_insn_not_found (insn);
2714 : 245802100 : }
2715 : :
2716 : : /* Do cached extract_insn, constrain_operands and complain about failures.
2717 : : Used by insn_attrtab. */
2718 : : void
2719 : 8043095110 : extract_constrain_insn_cached (rtx_insn *insn)
2720 : : {
2721 : 8043095110 : extract_insn_cached (insn);
2722 : 8043095110 : if (which_alternative == -1
2723 : 8043095110 : && !constrain_operands (reload_completed,
2724 : : get_enabled_alternatives (insn)))
2725 : 0 : fatal_insn_not_found (insn);
2726 : 8043095110 : }
2727 : :
2728 : : /* Do cached constrain_operands on INSN and complain about failures. */
2729 : : bool
2730 : 290886966 : constrain_operands_cached (rtx_insn *insn, int strict)
2731 : : {
2732 : 290886966 : if (which_alternative == -1)
2733 : 86605330 : return constrain_operands (strict, get_enabled_alternatives (insn));
2734 : : else
2735 : : return true;
2736 : : }
2737 : :
2738 : : /* Analyze INSN and fill in recog_data. */
2739 : :
2740 : : void
2741 : 1849692032 : extract_insn (rtx_insn *insn)
2742 : : {
2743 : 1849692032 : int i;
2744 : 1849692032 : int icode;
2745 : 1849692032 : int noperands;
2746 : 1849692032 : rtx body = PATTERN (insn);
2747 : :
2748 : 1849692032 : recog_data.n_operands = 0;
2749 : 1849692032 : recog_data.n_alternatives = 0;
2750 : 1849692032 : recog_data.n_dups = 0;
2751 : 1849692032 : recog_data.is_asm = false;
2752 : :
2753 : 1849692032 : switch (GET_CODE (body))
2754 : : {
2755 : : case USE:
2756 : : case CLOBBER:
2757 : : case ASM_INPUT:
2758 : : case ADDR_VEC:
2759 : : case ADDR_DIFF_VEC:
2760 : : case VAR_LOCATION:
2761 : : case DEBUG_MARKER:
2762 : : return;
2763 : :
2764 : 1500565215 : case SET:
2765 : 1500565215 : if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
2766 : 375 : goto asm_insn;
2767 : : else
2768 : 1500564840 : goto normal_insn;
2769 : 190037053 : case PARALLEL:
2770 : 190037053 : if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
2771 : 186282497 : && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
2772 : 189638971 : || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
2773 : 189008675 : || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
2774 : 1035133 : goto asm_insn;
2775 : : else
2776 : 189001920 : goto normal_insn;
2777 : 1035631 : case ASM_OPERANDS:
2778 : 1035631 : asm_insn:
2779 : 1035631 : recog_data.n_operands = noperands = asm_noperands (body);
2780 : 1035631 : if (noperands >= 0)
2781 : : {
2782 : : /* This insn is an `asm' with operands. */
2783 : :
2784 : : /* expand_asm_operands makes sure there aren't too many operands. */
2785 : 1035631 : gcc_assert (noperands <= MAX_RECOG_OPERANDS);
2786 : :
2787 : : /* Now get the operand values and constraints out of the insn. */
2788 : 1035631 : decode_asm_operands (body, recog_data.operand,
2789 : : recog_data.operand_loc,
2790 : : recog_data.constraints,
2791 : : recog_data.operand_mode, NULL);
2792 : 1035631 : memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
2793 : 1035631 : if (noperands > 0)
2794 : : {
2795 : 473905 : const char *p = recog_data.constraints[0];
2796 : 473905 : recog_data.n_alternatives = 1;
2797 : 1347672 : while (*p)
2798 : 873767 : recog_data.n_alternatives += (*p++ == ',');
2799 : : }
2800 : 1035631 : recog_data.is_asm = true;
2801 : 1035631 : break;
2802 : : }
2803 : 0 : fatal_insn_not_found (insn);
2804 : :
2805 : 1740753209 : default:
2806 : 1740753209 : normal_insn:
2807 : : /* Ordinary insn: recognize it, get the operands via insn_extract
2808 : : and get the constraints. */
2809 : :
2810 : 1740753209 : icode = recog_memoized (insn);
2811 : 1740753209 : if (icode < 0)
2812 : 0 : fatal_insn_not_found (insn);
2813 : :
2814 : 1740753209 : recog_data.n_operands = noperands = insn_data[icode].n_operands;
2815 : 1740753209 : recog_data.n_alternatives = insn_data[icode].n_alternatives;
2816 : 1740753209 : recog_data.n_dups = insn_data[icode].n_dups;
2817 : :
2818 : 1740753209 : insn_extract (insn);
2819 : :
2820 : 7182157074 : for (i = 0; i < noperands; i++)
2821 : : {
2822 : 3700650656 : recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
2823 : 3700650656 : recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
2824 : 3700650656 : recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
2825 : : /* VOIDmode match_operands gets mode from their real operand. */
2826 : 3700650656 : if (recog_data.operand_mode[i] == VOIDmode)
2827 : 357965352 : recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
2828 : : }
2829 : : }
2830 : 5443982120 : for (i = 0; i < noperands; i++)
2831 : 3702193280 : recog_data.operand_type[i]
2832 : 5979465066 : = (recog_data.constraints[i][0] == '=' ? OP_OUT
2833 : 2277271786 : : recog_data.constraints[i][0] == '+' ? OP_INOUT
2834 : : : OP_IN);
2835 : :
2836 : 1741788840 : gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES);
2837 : :
2838 : 1741788840 : recog_data.insn = NULL;
2839 : 1741788840 : which_alternative = -1;
2840 : : }
2841 : :
2842 : : /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS
2843 : : operands, N_ALTERNATIVES alternatives and constraint strings
2844 : : CONSTRAINTS. OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries
2845 : : and CONSTRAINTS has N_OPERANDS entries. OPLOC should be passed in
2846 : : if the insn is an asm statement and preprocessing should take the
2847 : : asm operands into account, e.g. to determine whether they could be
2848 : : addresses in constraints that require addresses; it should then
2849 : : point to an array of pointers to each operand. */
2850 : :
2851 : : void
2852 : 4574268 : preprocess_constraints (int n_operands, int n_alternatives,
2853 : : const char **constraints,
2854 : : operand_alternative *op_alt_base,
2855 : : rtx **oploc)
2856 : : {
2857 : 11727896 : for (int i = 0; i < n_operands; i++)
2858 : : {
2859 : 7153628 : int j;
2860 : 7153628 : struct operand_alternative *op_alt;
2861 : 7153628 : const char *p = constraints[i];
2862 : :
2863 : 7153628 : op_alt = op_alt_base;
2864 : :
2865 : 44553336 : for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
2866 : : {
2867 : 37399708 : op_alt[i].cl = NO_REGS;
2868 : 37399708 : op_alt[i].register_filters = 0;
2869 : 37399708 : op_alt[i].constraint = p;
2870 : 37399708 : op_alt[i].matches = -1;
2871 : 37399708 : op_alt[i].matched = -1;
2872 : :
2873 : 37399708 : if (*p == '\0' || *p == ',')
2874 : : {
2875 : 1575060 : op_alt[i].anything_ok = 1;
2876 : 1575060 : continue;
2877 : : }
2878 : :
2879 : 95784818 : for (;;)
2880 : : {
2881 : 95784818 : char c = *p;
2882 : 95784818 : if (c == '#')
2883 : 0 : do
2884 : 0 : c = *++p;
2885 : 0 : while (c != ',' && c != '\0');
2886 : 95784818 : if (c == ',' || c == '\0')
2887 : : {
2888 : 35824648 : p++;
2889 : 35824648 : break;
2890 : : }
2891 : :
2892 : 59960170 : switch (c)
2893 : : {
2894 : 5360859 : case '?':
2895 : 5360859 : op_alt[i].reject += 6;
2896 : 5360859 : break;
2897 : 386116 : case '!':
2898 : 386116 : op_alt[i].reject += 600;
2899 : 386116 : break;
2900 : 51388 : case '&':
2901 : 51388 : op_alt[i].earlyclobber = 1;
2902 : 51388 : break;
2903 : :
2904 : 1689905 : case '0': case '1': case '2': case '3': case '4':
2905 : 1689905 : case '5': case '6': case '7': case '8': case '9':
2906 : 1689905 : {
2907 : 1689905 : char *end;
2908 : 1689905 : op_alt[i].matches = strtoul (p, &end, 10);
2909 : 1689905 : op_alt[op_alt[i].matches].matched = i;
2910 : 1689905 : p = end;
2911 : : }
2912 : 1689905 : continue;
2913 : :
2914 : 29726 : case 'X':
2915 : 29726 : op_alt[i].anything_ok = 1;
2916 : 29726 : break;
2917 : :
2918 : 199744 : case 'g':
2919 : 199744 : op_alt[i].cl =
2920 : 199744 : reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
2921 : 199744 : break;
2922 : :
2923 : 52242432 : default:
2924 : 52242432 : enum constraint_num cn = lookup_constraint (p);
2925 : 52242432 : enum reg_class cl;
2926 : 52242432 : switch (get_constraint_type (cn))
2927 : : {
2928 : 37490351 : case CT_REGISTER:
2929 : 37490351 : cl = reg_class_for_constraint (cn);
2930 : 26651362 : if (cl != NO_REGS)
2931 : : {
2932 : 23143351 : op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
2933 : 23143351 : auto filter_id = get_register_filter_id (cn);
2934 : 23143351 : if (filter_id >= 0)
2935 : : op_alt[i].register_filters |= 1U << filter_id;
2936 : : }
2937 : : break;
2938 : :
2939 : : case CT_CONST_INT:
2940 : : break;
2941 : :
2942 : 7294803 : case CT_MEMORY:
2943 : 7294803 : case CT_SPECIAL_MEMORY:
2944 : 7294803 : case CT_RELAXED_MEMORY:
2945 : 7294803 : op_alt[i].memory_ok = 1;
2946 : 7294803 : break;
2947 : :
2948 : 82540 : case CT_ADDRESS:
2949 : 82540 : if (oploc && !address_operand (*oploc[i], VOIDmode))
2950 : : break;
2951 : :
2952 : 82521 : op_alt[i].is_address = 1;
2953 : 82521 : op_alt[i].cl
2954 : 82521 : = (reg_class_subunion
2955 : 82521 : [(int) op_alt[i].cl]
2956 : 82521 : [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
2957 : 82521 : ADDRESS, SCRATCH)]);
2958 : 82521 : break;
2959 : :
2960 : : case CT_FIXED_FORM:
2961 : : break;
2962 : : }
2963 : : break;
2964 : 1689905 : }
2965 : 58270265 : p += CONSTRAINT_LEN (c, p);
2966 : : }
2967 : : }
2968 : : }
2969 : 4574268 : }
2970 : :
2971 : : /* Return an array of operand_alternative instructions for
2972 : : instruction ICODE. */
2973 : :
2974 : : const operand_alternative *
2975 : 270935152 : preprocess_insn_constraints (unsigned int icode)
2976 : : {
2977 : 270935152 : gcc_checking_assert (IN_RANGE (icode, 0, NUM_INSN_CODES - 1));
2978 : 270935152 : if (this_target_recog->x_op_alt[icode])
2979 : : return this_target_recog->x_op_alt[icode];
2980 : :
2981 : 5238149 : int n_operands = insn_data[icode].n_operands;
2982 : 5238149 : if (n_operands == 0)
2983 : : return 0;
2984 : : /* Always provide at least one alternative so that which_op_alt ()
2985 : : works correctly. If the instruction has 0 alternatives (i.e. all
2986 : : constraint strings are empty) then each operand in this alternative
2987 : : will have anything_ok set. */
2988 : 2794202 : int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
2989 : 2794202 : int n_entries = n_operands * n_alternatives;
2990 : :
2991 : 2794202 : operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
2992 : 2794202 : const char **constraints = XALLOCAVEC (const char *, n_operands);
2993 : :
2994 : 9450757 : for (int i = 0; i < n_operands; ++i)
2995 : 6656555 : constraints[i] = insn_data[icode].operand[i].constraint;
2996 : 2794202 : preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
2997 : : NULL);
2998 : :
2999 : 2794202 : this_target_recog->x_op_alt[icode] = op_alt;
3000 : 2794202 : return op_alt;
3001 : : }
3002 : :
3003 : : /* After calling extract_insn, you can use this function to extract some
3004 : : information from the constraint strings into a more usable form.
3005 : : The collected data is stored in recog_op_alt. */
3006 : :
3007 : : void
3008 : 184236682 : preprocess_constraints (rtx_insn *insn)
3009 : : {
3010 : 184236682 : int icode = INSN_CODE (insn);
3011 : 184236682 : if (icode >= 0)
3012 : 182503143 : recog_op_alt = preprocess_insn_constraints (icode);
3013 : : else
3014 : : {
3015 : 1733539 : int n_operands = recog_data.n_operands;
3016 : 1733539 : int n_alternatives = recog_data.n_alternatives;
3017 : 1733539 : int n_entries = n_operands * n_alternatives;
3018 : 1733539 : memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
3019 : 1733539 : preprocess_constraints (n_operands, n_alternatives,
3020 : : recog_data.constraints, asm_op_alt,
3021 : : NULL);
3022 : 1733539 : recog_op_alt = asm_op_alt;
3023 : : }
3024 : 184236682 : }
3025 : :
3026 : : /* Check the operands of an insn against the insn's operand constraints
3027 : : and return 1 if they match any of the alternatives in ALTERNATIVES.
3028 : :
3029 : : The information about the insn's operands, constraints, operand modes
3030 : : etc. is obtained from the global variables set up by extract_insn.
3031 : :
3032 : : WHICH_ALTERNATIVE is set to a number which indicates which
3033 : : alternative of constraints was matched: 0 for the first alternative,
3034 : : 1 for the next, etc.
3035 : :
3036 : : In addition, when two operands are required to match
3037 : : and it happens that the output operand is (reg) while the
3038 : : input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
3039 : : make the output operand look like the input.
3040 : : This is because the output operand is the one the template will print.
3041 : :
3042 : : This is used in final, just before printing the assembler code and by
3043 : : the routines that determine an insn's attribute.
3044 : :
3045 : : If STRICT is a positive nonzero value, it means that we have been
3046 : : called after reload has been completed. In that case, we must
3047 : : do all checks strictly. If it is zero, it means that we have been called
3048 : : before reload has completed. In that case, we first try to see if we can
3049 : : find an alternative that matches strictly. If not, we try again, this
3050 : : time assuming that reload will fix up the insn. This provides a "best
3051 : : guess" for the alternative and is used to compute attributes of insns prior
3052 : : to reload. A negative value of STRICT is used for this internal call. */
3053 : :
3054 : : struct funny_match
3055 : : {
3056 : : int this_op, other;
3057 : : };
3058 : :
3059 : : bool
3060 : 1025721784 : constrain_operands (int strict, alternative_mask alternatives)
3061 : : {
3062 : 1025723212 : const char *constraints[MAX_RECOG_OPERANDS];
3063 : 1025723212 : int matching_operands[MAX_RECOG_OPERANDS];
3064 : 1025723212 : int earlyclobber[MAX_RECOG_OPERANDS];
3065 : 1025723212 : int c;
3066 : :
3067 : 1025723212 : struct funny_match funny_match[MAX_RECOG_OPERANDS];
3068 : 1025723212 : int funny_match_index;
3069 : :
3070 : 1025723212 : which_alternative = 0;
3071 : 1025723212 : if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0)
3072 : : return true;
3073 : :
3074 : 3043767717 : for (c = 0; c < recog_data.n_operands; c++)
3075 : 2071954825 : constraints[c] = recog_data.constraints[c];
3076 : :
3077 : 3635275292 : do
3078 : : {
3079 : 3635275292 : int seen_earlyclobber_at = -1;
3080 : 3635275292 : int opno;
3081 : 3635275292 : bool lose = false;
3082 : 3635275292 : funny_match_index = 0;
3083 : :
3084 : 3635275292 : if (!TEST_BIT (alternatives, which_alternative))
3085 : : {
3086 : : int i;
3087 : :
3088 : 2448241419 : for (i = 0; i < recog_data.n_operands; i++)
3089 : 3282470438 : constraints[i] = skip_alternative (constraints[i]);
3090 : :
3091 : 807006200 : which_alternative++;
3092 : 807006200 : continue;
3093 : 807006200 : }
3094 : :
3095 : 8640278539 : for (opno = 0; opno < recog_data.n_operands; opno++)
3096 : 5812009447 : matching_operands[opno] = -1;
3097 : :
3098 : 8640278539 : for (opno = 0; opno < recog_data.n_operands; opno++)
3099 : : {
3100 : 5812009447 : rtx op = recog_data.operand[opno];
3101 : 5812009447 : machine_mode mode = GET_MODE (op);
3102 : 5812009447 : const char *p = constraints[opno];
3103 : 5812009447 : int offset = 0;
3104 : 5812009447 : bool win = false;
3105 : 5812009447 : int val;
3106 : 5812009447 : int len;
3107 : :
3108 : 5812009447 : earlyclobber[opno] = 0;
3109 : :
3110 : 5812009447 : if (GET_CODE (op) == SUBREG)
3111 : : {
3112 : 4528 : if (REG_P (SUBREG_REG (op))
3113 : 4528 : && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
3114 : 9 : offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
3115 : 9 : GET_MODE (SUBREG_REG (op)),
3116 : 9 : SUBREG_BYTE (op),
3117 : : GET_MODE (op));
3118 : 4528 : op = SUBREG_REG (op);
3119 : : }
3120 : :
3121 : : /* An empty constraint or empty alternative
3122 : : allows anything which matched the pattern. */
3123 : 5812009447 : if (*p == 0 || *p == ',')
3124 : 83419738 : win = true;
3125 : :
3126 : 14856091264 : do
3127 : 14856091264 : switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
3128 : : {
3129 : : case '\0':
3130 : : len = 0;
3131 : : break;
3132 : 5512406649 : case ',':
3133 : 5512406649 : c = '\0';
3134 : 5512406649 : break;
3135 : :
3136 : 0 : case '#':
3137 : : /* Ignore rest of this alternative as far as
3138 : : constraint checking is concerned. */
3139 : 0 : do
3140 : 0 : p++;
3141 : 0 : while (*p && *p != ',');
3142 : : len = 0;
3143 : : break;
3144 : :
3145 : 314727 : case '&':
3146 : 314727 : earlyclobber[opno] = 1;
3147 : 314727 : if (seen_earlyclobber_at < 0)
3148 : 299404 : seen_earlyclobber_at = opno;
3149 : : break;
3150 : :
3151 : 118364790 : case '0': case '1': case '2': case '3': case '4':
3152 : 118364790 : case '5': case '6': case '7': case '8': case '9':
3153 : 118364790 : {
3154 : : /* This operand must be the same as a previous one.
3155 : : This kind of constraint is used for instructions such
3156 : : as add when they take only two operands.
3157 : :
3158 : : Note that the lower-numbered operand is passed first.
3159 : :
3160 : : If we are not testing strictly, assume that this
3161 : : constraint will be satisfied. */
3162 : :
3163 : 118364790 : char *end;
3164 : 118364790 : int match;
3165 : :
3166 : 118364790 : match = strtoul (p, &end, 10);
3167 : 118364790 : p = end;
3168 : :
3169 : 118364790 : if (strict < 0)
3170 : : val = 1;
3171 : : else
3172 : : {
3173 : 118363378 : rtx op1 = recog_data.operand[match];
3174 : 118363378 : rtx op2 = recog_data.operand[opno];
3175 : 118363378 : val = operands_match_p (op1, op2);
3176 : : }
3177 : :
3178 : 118364790 : matching_operands[opno] = match;
3179 : 118364790 : matching_operands[match] = opno;
3180 : :
3181 : 118364790 : if (val != 0)
3182 : 100229623 : win = true;
3183 : :
3184 : : /* If output is *x and input is *--x, arrange later
3185 : : to change the output to *--x as well, since the
3186 : : output op is the one that will be printed. */
3187 : 118364790 : if (val == 2 && strict > 0)
3188 : : {
3189 : 0 : funny_match[funny_match_index].this_op = opno;
3190 : 0 : funny_match[funny_match_index++].other = match;
3191 : : }
3192 : : }
3193 : 118364790 : len = 0;
3194 : 118364790 : break;
3195 : :
3196 : 241080 : case 'p':
3197 : : /* p is used for address_operands. When we are called by
3198 : : gen_reload, no one will have checked that the address is
3199 : : strictly valid, i.e., that all pseudos requiring hard regs
3200 : : have gotten them. We also want to make sure we have a
3201 : : valid mode. */
3202 : 241080 : {
3203 : 482160 : auto mem_mode = (recog_data.is_asm
3204 : 241080 : ? VOIDmode
3205 : : : recog_data.operand_mode[opno]);
3206 : 241080 : if ((GET_MODE (op) == VOIDmode
3207 : 241080 : || SCALAR_INT_MODE_P (GET_MODE (op)))
3208 : 482135 : && (strict <= 0
3209 : 241080 : || strict_memory_address_p (mem_mode, op)))
3210 : 241015 : win = true;
3211 : : break;
3212 : : }
3213 : :
3214 : : /* No need to check general_operand again;
3215 : : it was done in insn-recog.cc. Well, except that reload
3216 : : doesn't check the validity of its replacements, but
3217 : : that should only matter when there's a bug. */
3218 : 118469515 : case 'g':
3219 : : /* Anything goes unless it is a REG and really has a hard reg
3220 : : but the hard reg is not in the class GENERAL_REGS. */
3221 : 118469515 : if (REG_P (op))
3222 : : {
3223 : 45390455 : if (strict < 0
3224 : : || GENERAL_REGS == ALL_REGS
3225 : 45390397 : || (reload_in_progress
3226 : 0 : && REGNO (op) >= FIRST_PSEUDO_REGISTER)
3227 : 90780852 : || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
3228 : : win = true;
3229 : : }
3230 : 73079060 : else if (strict < 0 || general_operand (op, mode))
3231 : : win = true;
3232 : : break;
3233 : :
3234 : 8806691705 : default:
3235 : 8806691705 : {
3236 : 8806691705 : enum constraint_num cn = lookup_constraint (p);
3237 : 8806691705 : enum reg_class cl = reg_class_for_constraint (cn);
3238 : 4048606719 : if (cl != NO_REGS)
3239 : : {
3240 : 3877305516 : auto *filter = get_register_filter (cn);
3241 : 3877305516 : if (strict < 0
3242 : 3877302675 : || (strict == 0
3243 : 94587 : && REG_P (op)
3244 : 74787 : && REGNO (op) >= FIRST_PSEUDO_REGISTER)
3245 : 38717 : || (strict == 0 && GET_CODE (op) == SCRATCH)
3246 : 7754552321 : || (REG_P (op)
3247 : 2848392492 : && reg_fits_class_p (op, cl, offset, mode)
3248 : : && (!filter
3249 : : || TEST_HARD_REG_BIT (*filter,
3250 : : REGNO (op) + offset))))
3251 : : win = true;
3252 : : }
3253 : :
3254 : 4929386189 : else if (constraint_satisfied_p (op, cn))
3255 : : win = true;
3256 : :
3257 : 4158485536 : else if ((insn_extra_memory_constraint (cn)
3258 : : || insn_extra_relaxed_memory_constraint (cn))
3259 : : /* Every memory operand can be reloaded to fit. */
3260 : 4158485536 : && ((strict < 0 && MEM_P (op))
3261 : : /* Before reload, accept what reload can turn
3262 : : into a mem. */
3263 : 1068 : || (strict < 0 && CONSTANT_P (op))
3264 : : /* Before reload, accept a pseudo or hard register,
3265 : : since LRA can turn it into a mem. */
3266 : 1032 : || (strict < 0 && targetm.lra_p () && REG_P (op))
3267 : : /* During reload, accept a pseudo */
3268 : 855918485 : || (reload_in_progress && REG_P (op)
3269 : 0 : && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
3270 : : win = true;
3271 : 4158484468 : else if (insn_extra_address_constraint (cn)
3272 : : /* Every address operand can be reloaded to fit. */
3273 : 4158484468 : && strict < 0)
3274 : : win = true;
3275 : : /* Cater to architectures like IA-64 that define extra memory
3276 : : constraints without using define_memory_constraint. */
3277 : 4158484468 : else if (reload_in_progress
3278 : 0 : && REG_P (op)
3279 : 0 : && REGNO (op) >= FIRST_PSEUDO_REGISTER
3280 : 0 : && reg_renumber[REGNO (op)] < 0
3281 : 0 : && reg_equiv_mem (REGNO (op)) != 0
3282 : 4158484468 : && constraint_satisfied_p
3283 : 0 : (reg_equiv_mem (REGNO (op)), cn))
3284 : : win = true;
3285 : : break;
3286 : : }
3287 : : }
3288 : 14856091264 : while (p += len, c);
3289 : :
3290 : 5812009447 : constraints[opno] = p;
3291 : : /* If this operand did not win somehow,
3292 : : this alternative loses. */
3293 : 5812009447 : if (! win)
3294 : 2857480698 : lose = true;
3295 : : }
3296 : : /* This alternative won; the operands are ok.
3297 : : Change whichever operands this alternative says to change. */
3298 : 2828269092 : if (! lose)
3299 : : {
3300 : 970513527 : int opno, eopno;
3301 : :
3302 : : /* See if any earlyclobber operand conflicts with some other
3303 : : operand. */
3304 : :
3305 : 970513527 : if (strict > 0 && seen_earlyclobber_at >= 0)
3306 : 939995 : for (eopno = seen_earlyclobber_at;
3307 : 1238491 : eopno < recog_data.n_operands;
3308 : : eopno++)
3309 : : /* Ignore earlyclobber operands now in memory,
3310 : : because we would often report failure when we have
3311 : : two memory operands, one of which was formerly a REG. */
3312 : 939995 : if (earlyclobber[eopno]
3313 : 313819 : && REG_P (recog_data.operand[eopno]))
3314 : 1604601 : for (opno = 0; opno < recog_data.n_operands; opno++)
3315 : 1290782 : if ((MEM_P (recog_data.operand[opno])
3316 : 1154997 : || recog_data.operand_type[opno] != OP_OUT)
3317 : 776649 : && opno != eopno
3318 : : /* Ignore things like match_operator operands. */
3319 : 776086 : && *recog_data.constraints[opno] != 0
3320 : 803267 : && ! (matching_operands[opno] == eopno
3321 : 95955 : && operands_match_p (recog_data.operand[opno],
3322 : : recog_data.operand[eopno]))
3323 : 1904175 : && ! safe_from_earlyclobber (recog_data.operand[opno],
3324 : : recog_data.operand[eopno]))
3325 : : lose = true;
3326 : :
3327 : 970513527 : if (! lose)
3328 : : {
3329 : 970513466 : while (--funny_match_index >= 0)
3330 : : {
3331 : 0 : recog_data.operand[funny_match[funny_match_index].other]
3332 : 0 : = recog_data.operand[funny_match[funny_match_index].this_op];
3333 : : }
3334 : :
3335 : : /* For operands without < or > constraints reject side-effects. */
3336 : : if (AUTO_INC_DEC && recog_data.is_asm)
3337 : : {
3338 : : for (opno = 0; opno < recog_data.n_operands; opno++)
3339 : : if (MEM_P (recog_data.operand[opno]))
3340 : : switch (GET_CODE (XEXP (recog_data.operand[opno], 0)))
3341 : : {
3342 : : case PRE_INC:
3343 : : case POST_INC:
3344 : : case PRE_DEC:
3345 : : case POST_DEC:
3346 : : case PRE_MODIFY:
3347 : : case POST_MODIFY:
3348 : : if (strchr (recog_data.constraints[opno], '<') == NULL
3349 : : && strchr (recog_data.constraints[opno], '>')
3350 : : == NULL)
3351 : : return false;
3352 : : break;
3353 : : default:
3354 : : break;
3355 : : }
3356 : : }
3357 : :
3358 : : return true;
3359 : : }
3360 : : }
3361 : :
3362 : 1857755626 : which_alternative++;
3363 : : }
3364 : 2664761826 : while (which_alternative < recog_data.n_alternatives);
3365 : :
3366 : 1299426 : which_alternative = -1;
3367 : : /* If we are about to reject this, but we are not to test strictly,
3368 : : try a very loose test. Only return failure if it fails also. */
3369 : 1299426 : if (strict == 0)
3370 : : return constrain_operands (-1, alternatives);
3371 : : else
3372 : : return false;
3373 : : }
3374 : :
3375 : : /* Return true iff OPERAND (assumed to be a REG rtx)
3376 : : is a hard reg in class CLASS when its regno is offset by OFFSET
3377 : : and changed to mode MODE.
3378 : : If REG occupies multiple hard regs, all of them must be in CLASS. */
3379 : :
3380 : : bool
3381 : 3149929029 : reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
3382 : : machine_mode mode)
3383 : : {
3384 : 3149929029 : unsigned int regno = REGNO (operand);
3385 : :
3386 : 3149929029 : if (cl == NO_REGS)
3387 : : return false;
3388 : :
3389 : : /* Regno must not be a pseudo register. Offset may be negative. */
3390 : 3029033365 : return (HARD_REGISTER_NUM_P (regno)
3391 : 3029030796 : && HARD_REGISTER_NUM_P (regno + offset)
3392 : 6058064161 : && in_hard_reg_set_p (reg_class_contents[(int) cl], mode,
3393 : : regno + offset));
3394 : : }
3395 : :
3396 : : /* Split single instruction. Helper function for split_all_insns and
3397 : : split_all_insns_noflow. Return last insn in the sequence if successful,
3398 : : or NULL if unsuccessful. */
3399 : :
3400 : : static rtx_insn *
3401 : 332520179 : split_insn (rtx_insn *insn)
3402 : : {
3403 : : /* Split insns here to get max fine-grain parallelism. */
3404 : 332520179 : rtx_insn *first = PREV_INSN (insn);
3405 : 332520179 : rtx_insn *last = try_split (PATTERN (insn), insn, 1);
3406 : 332520179 : rtx insn_set, last_set, note;
3407 : :
3408 : 332520179 : if (last == insn)
3409 : : return NULL;
3410 : :
3411 : : /* If the original instruction was a single set that was known to be
3412 : : equivalent to a constant, see if we can say the same about the last
3413 : : instruction in the split sequence. The two instructions must set
3414 : : the same destination. */
3415 : 5870232 : insn_set = single_set (insn);
3416 : 5870232 : if (insn_set)
3417 : : {
3418 : 5789065 : last_set = single_set (last);
3419 : 5789065 : if (last_set && rtx_equal_p (SET_DEST (last_set), SET_DEST (insn_set)))
3420 : : {
3421 : 2711031 : note = find_reg_equal_equiv_note (insn);
3422 : 2711031 : if (note && CONSTANT_P (XEXP (note, 0)))
3423 : 85632 : set_unique_reg_note (last, REG_EQUAL, XEXP (note, 0));
3424 : 2625399 : else if (CONSTANT_P (SET_SRC (insn_set)))
3425 : 84 : set_unique_reg_note (last, REG_EQUAL,
3426 : : copy_rtx (SET_SRC (insn_set)));
3427 : : }
3428 : : }
3429 : :
3430 : : /* try_split returns the NOTE that INSN became. */
3431 : 5870232 : SET_INSN_DELETED (insn);
3432 : :
3433 : : /* ??? Coddle to md files that generate subregs in post-reload
3434 : : splitters instead of computing the proper hard register. */
3435 : 5870232 : if (reload_completed && first != last)
3436 : : {
3437 : 5495158 : first = NEXT_INSN (first);
3438 : 2617506 : for (;;)
3439 : : {
3440 : 8112664 : if (INSN_P (first))
3441 : 8109543 : cleanup_subreg_operands (first);
3442 : 8112664 : if (first == last)
3443 : : break;
3444 : 2617506 : first = NEXT_INSN (first);
3445 : : }
3446 : : }
3447 : :
3448 : : return last;
3449 : : }
3450 : :
3451 : : /* Split all insns in the function. If UPD_LIFE, update life info after. */
3452 : :
3453 : : void
3454 : 3841303 : split_all_insns (void)
3455 : : {
3456 : 3841303 : bool changed;
3457 : 3841303 : bool need_cfg_cleanup = false;
3458 : 3841303 : basic_block bb;
3459 : :
3460 : 3841303 : auto_sbitmap blocks (last_basic_block_for_fn (cfun));
3461 : 3841303 : bitmap_clear (blocks);
3462 : 3841303 : changed = false;
3463 : :
3464 : 39879836 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
3465 : : {
3466 : 36038533 : rtx_insn *insn, *next;
3467 : 36038533 : bool finish = false;
3468 : :
3469 : 36038533 : rtl_profile_for_bb (bb);
3470 : 442077419 : for (insn = BB_HEAD (bb); !finish ; insn = next)
3471 : : {
3472 : : /* Can't use `next_real_insn' because that might go across
3473 : : CODE_LABELS and short-out basic blocks. */
3474 : 406038886 : next = NEXT_INSN (insn);
3475 : 406038886 : finish = (insn == BB_END (bb));
3476 : :
3477 : : /* If INSN has a REG_EH_REGION note and we split INSN, the
3478 : : resulting split may not have/need REG_EH_REGION notes.
3479 : :
3480 : : If that happens and INSN was the last reference to the
3481 : : given EH region, then the EH region will become unreachable.
3482 : : We cannot leave the unreachable blocks in the CFG as that
3483 : : will trigger a checking failure.
3484 : :
3485 : : So track if INSN has a REG_EH_REGION note. If so and we
3486 : : split INSN, then trigger a CFG cleanup. */
3487 : 406038886 : rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3488 : 406038886 : if (INSN_P (insn))
3489 : : {
3490 : 332560193 : rtx set = single_set (insn);
3491 : :
3492 : : /* Don't split no-op move insns. These should silently
3493 : : disappear later in final. Splitting such insns would
3494 : : break the code that handles LIBCALL blocks. */
3495 : 332560193 : if (set && set_noop_p (set))
3496 : : {
3497 : : /* Nops get in the way while scheduling, so delete them
3498 : : now if register allocation has already been done. It
3499 : : is too risky to try to do this before register
3500 : : allocation, and there are unlikely to be very many
3501 : : nops then anyways. */
3502 : 40014 : if (reload_completed)
3503 : 39989 : delete_insn_and_edges (insn);
3504 : 40014 : if (note)
3505 : 406038886 : need_cfg_cleanup = true;
3506 : : }
3507 : : else
3508 : : {
3509 : 332520179 : if (split_insn (insn))
3510 : : {
3511 : 5870232 : bitmap_set_bit (blocks, bb->index);
3512 : 5870232 : changed = true;
3513 : 5870232 : if (note)
3514 : 2588 : need_cfg_cleanup = true;
3515 : : }
3516 : : }
3517 : : }
3518 : : }
3519 : : }
3520 : :
3521 : 3841303 : default_rtl_profile ();
3522 : 3841303 : if (changed)
3523 : : {
3524 : 719587 : find_many_sub_basic_blocks (blocks);
3525 : :
3526 : : /* Splitting could drop an REG_EH_REGION if it potentially
3527 : : trapped in its original form, but does not in its split
3528 : : form. Consider a FLOAT_TRUNCATE which splits into a memory
3529 : : store/load pair and -fnon-call-exceptions. */
3530 : 719587 : if (need_cfg_cleanup)
3531 : 1255 : cleanup_cfg (0);
3532 : : }
3533 : :
3534 : 3841303 : checking_verify_flow_info ();
3535 : 3841303 : }
3536 : :
3537 : : /* Same as split_all_insns, but do not expect CFG to be available.
3538 : : Used by machine dependent reorg passes. */
3539 : :
3540 : : void
3541 : 0 : split_all_insns_noflow (void)
3542 : : {
3543 : 0 : rtx_insn *next, *insn;
3544 : :
3545 : 0 : for (insn = get_insns (); insn; insn = next)
3546 : : {
3547 : 0 : next = NEXT_INSN (insn);
3548 : 0 : if (INSN_P (insn))
3549 : : {
3550 : : /* Don't split no-op move insns. These should silently
3551 : : disappear later in final. Splitting such insns would
3552 : : break the code that handles LIBCALL blocks. */
3553 : 0 : rtx set = single_set (insn);
3554 : 0 : if (set && set_noop_p (set))
3555 : : {
3556 : : /* Nops get in the way while scheduling, so delete them
3557 : : now if register allocation has already been done. It
3558 : : is too risky to try to do this before register
3559 : : allocation, and there are unlikely to be very many
3560 : : nops then anyways.
3561 : :
3562 : : ??? Should we use delete_insn when the CFG isn't valid? */
3563 : 0 : if (reload_completed)
3564 : 0 : delete_insn_and_edges (insn);
3565 : : }
3566 : : else
3567 : 0 : split_insn (insn);
3568 : : }
3569 : : }
3570 : 0 : }
3571 : :
3572 : : struct peep2_insn_data
3573 : : {
3574 : : rtx_insn *insn;
3575 : : regset live_before;
3576 : : };
3577 : :
3578 : : static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
3579 : : static int peep2_current;
3580 : :
3581 : : static bool peep2_do_rebuild_jump_labels;
3582 : : static bool peep2_do_cleanup_cfg;
3583 : :
3584 : : /* The number of instructions available to match a peep2. */
3585 : : int peep2_current_count;
3586 : :
3587 : : /* A marker indicating the last insn of the block. The live_before regset
3588 : : for this element is correct, indicating DF_LIVE_OUT for the block. */
3589 : : #define PEEP2_EOB invalid_insn_rtx
3590 : :
3591 : : /* Wrap N to fit into the peep2_insn_data buffer. */
3592 : :
3593 : : static int
3594 : 393965868 : peep2_buf_position (int n)
3595 : : {
3596 : 0 : if (n >= MAX_INSNS_PER_PEEP2 + 1)
3597 : 131639542 : n -= MAX_INSNS_PER_PEEP2 + 1;
3598 : 393948653 : return n;
3599 : : }
3600 : :
3601 : : /* Return the Nth non-note insn after `current', or return NULL_RTX if it
3602 : : does not exist. Used by the recognizer to find the next insn to match
3603 : : in a multi-insn pattern. */
3604 : :
3605 : : rtx_insn *
3606 : 204047442 : peep2_next_insn (int n)
3607 : : {
3608 : 204047442 : gcc_assert (n <= peep2_current_count);
3609 : :
3610 : 204047442 : n = peep2_buf_position (peep2_current + n);
3611 : :
3612 : 204047442 : return peep2_insn_data[n].insn;
3613 : : }
3614 : :
3615 : : /* Return true if REGNO is dead before the Nth non-note insn
3616 : : after `current'. */
3617 : :
3618 : : bool
3619 : 12297395 : peep2_regno_dead_p (int ofs, int regno)
3620 : : {
3621 : 12297395 : gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
3622 : :
3623 : 12297395 : ofs = peep2_buf_position (peep2_current + ofs);
3624 : :
3625 : 12297395 : gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
3626 : :
3627 : 12297395 : return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno);
3628 : : }
3629 : :
3630 : : /* Similarly for a REG. */
3631 : :
3632 : : bool
3633 : 318225 : peep2_reg_dead_p (int ofs, rtx reg)
3634 : : {
3635 : 318225 : gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
3636 : :
3637 : 318225 : ofs = peep2_buf_position (peep2_current + ofs);
3638 : :
3639 : 318225 : gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
3640 : :
3641 : 318225 : unsigned int end_regno = END_REGNO (reg);
3642 : 402695 : for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
3643 : 318225 : if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno))
3644 : : return false;
3645 : : return true;
3646 : : }
3647 : :
3648 : : /* Regno offset to be used in the register search. */
3649 : : static int search_ofs;
3650 : :
3651 : : /* Try to find a hard register of mode MODE, matching the register class in
3652 : : CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
3653 : : remains available until the end of LAST_INSN. LAST_INSN may be NULL_RTX,
3654 : : in which case the only condition is that the register must be available
3655 : : before CURRENT_INSN.
3656 : : Registers that already have bits set in REG_SET will not be considered.
3657 : :
3658 : : If an appropriate register is available, it will be returned and the
3659 : : corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
3660 : : returned. */
3661 : :
3662 : : rtx
3663 : 568685 : peep2_find_free_register (int from, int to, const char *class_str,
3664 : : machine_mode mode, HARD_REG_SET *reg_set)
3665 : : {
3666 : 568685 : enum reg_class cl;
3667 : 568685 : HARD_REG_SET live;
3668 : 568685 : df_ref def;
3669 : 568685 : int i;
3670 : :
3671 : 568685 : gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
3672 : 568685 : gcc_assert (to < MAX_INSNS_PER_PEEP2 + 1);
3673 : :
3674 : 568685 : from = peep2_buf_position (peep2_current + from);
3675 : 568685 : to = peep2_buf_position (peep2_current + to);
3676 : :
3677 : 568685 : gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
3678 : 568685 : REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);
3679 : :
3680 : 568685 : while (from != to)
3681 : : {
3682 : 17215 : gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
3683 : :
3684 : : /* Don't use registers set or clobbered by the insn. */
3685 : 68860 : FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn)
3686 : 51645 : SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
3687 : :
3688 : 603115 : from = peep2_buf_position (from + 1);
3689 : : }
3690 : :
3691 : 568685 : cl = reg_class_for_constraint (lookup_constraint (class_str));
3692 : :
3693 : 5106514 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3694 : : {
3695 : 5103245 : int raw_regno, regno, j;
3696 : 5103245 : bool success;
3697 : :
3698 : : /* Distribute the free registers as much as possible. */
3699 : 5103245 : raw_regno = search_ofs + i;
3700 : 5103245 : if (raw_regno >= FIRST_PSEUDO_REGISTER)
3701 : 203614 : raw_regno -= FIRST_PSEUDO_REGISTER;
3702 : : #ifdef REG_ALLOC_ORDER
3703 : 5103245 : regno = reg_alloc_order[raw_regno];
3704 : : #else
3705 : : regno = raw_regno;
3706 : : #endif
3707 : :
3708 : : /* Can it support the mode we need? */
3709 : 5103245 : if (!targetm.hard_regno_mode_ok (regno, mode))
3710 : 1552072 : continue;
3711 : :
3712 : 4116589 : success = true;
3713 : 4116589 : for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
3714 : : {
3715 : : /* Don't allocate fixed registers. */
3716 : 3551173 : if (fixed_regs[regno + j])
3717 : : {
3718 : : success = false;
3719 : : break;
3720 : : }
3721 : : /* Don't allocate global registers. */
3722 : 1831561 : if (global_regs[regno + j])
3723 : : {
3724 : : success = false;
3725 : : break;
3726 : : }
3727 : : /* Make sure the register is of the right class. */
3728 : 1831561 : if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
3729 : : {
3730 : : success = false;
3731 : : break;
3732 : : }
3733 : : /* And that we don't create an extra save/restore. */
3734 : 989852 : if (! crtl->abi->clobbers_full_reg_p (regno + j)
3735 : 989852 : && ! df_regs_ever_live_p (regno + j))
3736 : : {
3737 : : success = false;
3738 : : break;
3739 : : }
3740 : :
3741 : 968264 : if (! targetm.hard_regno_scratch_ok (regno + j))
3742 : : {
3743 : : success = false;
3744 : : break;
3745 : : }
3746 : :
3747 : : /* And we don't clobber traceback for noreturn functions. */
3748 : 968136 : if ((regno + j == FRAME_POINTER_REGNUM
3749 : 968136 : || regno + j == HARD_FRAME_POINTER_REGNUM)
3750 : 45591 : && (! reload_completed || frame_pointer_needed))
3751 : : {
3752 : : success = false;
3753 : : break;
3754 : : }
3755 : :
3756 : 958188 : if (TEST_HARD_REG_BIT (*reg_set, regno + j)
3757 : 958188 : || TEST_HARD_REG_BIT (live, regno + j))
3758 : : {
3759 : : success = false;
3760 : : break;
3761 : : }
3762 : : }
3763 : :
3764 : 3551173 : if (success)
3765 : : {
3766 : 565416 : add_to_hard_reg_set (reg_set, mode, regno);
3767 : :
3768 : : /* Start the next search with the next register. */
3769 : 565416 : if (++raw_regno >= FIRST_PSEUDO_REGISTER)
3770 : 6909 : raw_regno = 0;
3771 : 565416 : search_ofs = raw_regno;
3772 : :
3773 : 565416 : return gen_rtx_REG (mode, regno);
3774 : : }
3775 : : }
3776 : :
3777 : 3269 : search_ofs = 0;
3778 : 3269 : return NULL_RTX;
3779 : : }
3780 : :
3781 : : /* Forget all currently tracked instructions, only remember current
3782 : : LIVE regset. */
3783 : :
3784 : : static void
3785 : 9787679 : peep2_reinit_state (regset live)
3786 : : {
3787 : 9787679 : int i;
3788 : :
3789 : : /* Indicate that all slots except the last holds invalid data. */
3790 : 68513753 : for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
3791 : 58726074 : peep2_insn_data[i].insn = NULL;
3792 : 9787679 : peep2_current_count = 0;
3793 : :
3794 : : /* Indicate that the last slot contains live_after data. */
3795 : 9787679 : peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
3796 : 9787679 : peep2_current = MAX_INSNS_PER_PEEP2;
3797 : :
3798 : 9787679 : COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
3799 : 9787679 : }
3800 : :
3801 : : /* Copies frame related info of an insn (OLD_INSN) to the single
3802 : : insn (NEW_INSN) that was obtained by splitting OLD_INSN. */
3803 : :
3804 : : void
3805 : 42086 : copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
3806 : : {
3807 : 42086 : bool any_note = false;
3808 : 42086 : rtx note;
3809 : :
3810 : 42086 : if (!RTX_FRAME_RELATED_P (old_insn))
3811 : : return;
3812 : :
3813 : 42086 : RTX_FRAME_RELATED_P (new_insn) = 1;
3814 : :
3815 : : /* Allow the backend to fill in a note during the split. */
3816 : 42086 : for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
3817 : 0 : switch (REG_NOTE_KIND (note))
3818 : : {
3819 : 0 : case REG_FRAME_RELATED_EXPR:
3820 : 0 : case REG_CFA_DEF_CFA:
3821 : 0 : case REG_CFA_ADJUST_CFA:
3822 : 0 : case REG_CFA_OFFSET:
3823 : 0 : case REG_CFA_REGISTER:
3824 : 0 : case REG_CFA_EXPRESSION:
3825 : 0 : case REG_CFA_RESTORE:
3826 : 0 : case REG_CFA_SET_VDRAP:
3827 : 0 : any_note = true;
3828 : 0 : break;
3829 : : default:
3830 : : break;
3831 : : }
3832 : :
3833 : : /* If the backend didn't supply a note, copy one over. */
3834 : 42086 : if (!any_note)
3835 : 126072 : for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
3836 : 83986 : switch (REG_NOTE_KIND (note))
3837 : : {
3838 : 41913 : case REG_FRAME_RELATED_EXPR:
3839 : 41913 : case REG_CFA_DEF_CFA:
3840 : 41913 : case REG_CFA_ADJUST_CFA:
3841 : 41913 : case REG_CFA_OFFSET:
3842 : 41913 : case REG_CFA_REGISTER:
3843 : 41913 : case REG_CFA_EXPRESSION:
3844 : 41913 : case REG_CFA_RESTORE:
3845 : 41913 : case REG_CFA_SET_VDRAP:
3846 : 41913 : add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
3847 : 41913 : any_note = true;
3848 : 41913 : break;
3849 : : default:
3850 : : break;
3851 : : }
3852 : :
3853 : : /* If there still isn't a note, make sure the unwind info sees the
3854 : : same expression as before the split. */
3855 : 42086 : if (!any_note)
3856 : : {
3857 : 173 : rtx old_set, new_set;
3858 : :
3859 : : /* The old insn had better have been simple, or annotated. */
3860 : 173 : old_set = single_set (old_insn);
3861 : 173 : gcc_assert (old_set != NULL);
3862 : :
3863 : 173 : new_set = single_set (new_insn);
3864 : 173 : if (!new_set || !rtx_equal_p (new_set, old_set))
3865 : 173 : add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
3866 : : }
3867 : :
3868 : : /* Copy prologue/epilogue status. This is required in order to keep
3869 : : proper placement of EPILOGUE_BEG and the DW_CFA_remember_state. */
3870 : 42086 : maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
3871 : : }
3872 : :
3873 : : /* While scanning basic block BB, we found a match of length MATCH_LEN + 1,
3874 : : starting at INSN. Perform the replacement, removing the old insns and
3875 : : replacing them with ATTEMPT. Returns the last insn emitted, or NULL
3876 : : if the replacement is rejected. */
3877 : :
3878 : : static rtx_insn *
3879 : 2113002 : peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
3880 : : {
3881 : 2113002 : int i;
3882 : 2113002 : rtx_insn *last, *before_try, *x;
3883 : 2113002 : rtx eh_note, as_note;
3884 : 2113002 : rtx_insn *old_insn;
3885 : 2113002 : rtx_insn *new_insn;
3886 : 2113002 : bool was_call = false;
3887 : :
3888 : : /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
3889 : : match more than one insn, or to be split into more than one insn. */
3890 : 2113002 : old_insn = peep2_insn_data[peep2_current].insn;
3891 : 2113002 : if (RTX_FRAME_RELATED_P (old_insn))
3892 : : {
3893 : 44620 : if (match_len != 0)
3894 : : return NULL;
3895 : :
3896 : : /* Look for one "active" insn. I.e. ignore any "clobber" insns that
3897 : : may be in the stream for the purpose of register allocation. */
3898 : 44620 : if (active_insn_p (attempt))
3899 : : new_insn = attempt;
3900 : : else
3901 : 32066 : new_insn = next_active_insn (attempt);
3902 : 44620 : if (next_active_insn (new_insn))
3903 : : return NULL;
3904 : :
3905 : : /* We have a 1-1 replacement. Copy over any frame-related info. */
3906 : 42069 : copy_frame_info_to_split_insn (old_insn, new_insn);
3907 : : }
3908 : :
3909 : : /* If we are splitting a CALL_INSN, look for the CALL_INSN
3910 : : in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
3911 : : cfg-related call notes. */
3912 : 4441926 : for (i = 0; i <= match_len; ++i)
3913 : : {
3914 : 2332840 : int j;
3915 : 2332840 : rtx note;
3916 : :
3917 : 2332840 : j = peep2_buf_position (peep2_current + i);
3918 : 2332840 : old_insn = peep2_insn_data[j].insn;
3919 : 2332840 : if (!CALL_P (old_insn))
3920 : 2331475 : continue;
3921 : 1365 : was_call = true;
3922 : :
3923 : : new_insn = attempt;
3924 : 1365 : while (new_insn != NULL_RTX)
3925 : : {
3926 : 1365 : if (CALL_P (new_insn))
3927 : : break;
3928 : 0 : new_insn = NEXT_INSN (new_insn);
3929 : : }
3930 : :
3931 : 1365 : gcc_assert (new_insn != NULL_RTX);
3932 : :
3933 : 1365 : CALL_INSN_FUNCTION_USAGE (new_insn)
3934 : 1365 : = CALL_INSN_FUNCTION_USAGE (old_insn);
3935 : 1365 : SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
3936 : :
3937 : 1365 : for (note = REG_NOTES (old_insn);
3938 : 6827 : note;
3939 : 5462 : note = XEXP (note, 1))
3940 : 5462 : switch (REG_NOTE_KIND (note))
3941 : : {
3942 : 0 : case REG_NORETURN:
3943 : 0 : case REG_SETJMP:
3944 : 0 : case REG_TM:
3945 : 0 : case REG_CALL_NOCF_CHECK:
3946 : 0 : add_reg_note (new_insn, REG_NOTE_KIND (note),
3947 : : XEXP (note, 0));
3948 : 0 : break;
3949 : : default:
3950 : : /* Discard all other reg notes. */
3951 : : break;
3952 : : }
3953 : :
3954 : : /* Croak if there is another call in the sequence. */
3955 : 1365 : while (++i <= match_len)
3956 : : {
3957 : 0 : j = peep2_buf_position (peep2_current + i);
3958 : 0 : old_insn = peep2_insn_data[j].insn;
3959 : 0 : gcc_assert (!CALL_P (old_insn));
3960 : : }
3961 : : break;
3962 : : }
3963 : :
3964 : : /* If we matched any instruction that had a REG_ARGS_SIZE, then
3965 : : move those notes over to the new sequence. */
3966 : 2110451 : as_note = NULL;
3967 : 4327206 : for (i = match_len; i >= 0; --i)
3968 : : {
3969 : 2332840 : int j = peep2_buf_position (peep2_current + i);
3970 : 2332840 : old_insn = peep2_insn_data[j].insn;
3971 : :
3972 : 2332840 : as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
3973 : 2332840 : if (as_note)
3974 : : break;
3975 : : }
3976 : :
3977 : 2110451 : i = peep2_buf_position (peep2_current + match_len);
3978 : 2110451 : eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
3979 : :
3980 : : /* Replace the old sequence with the new. */
3981 : 2110451 : rtx_insn *peepinsn = peep2_insn_data[i].insn;
3982 : 4220902 : last = emit_insn_after_setloc (attempt,
3983 : : peep2_insn_data[i].insn,
3984 : 2110451 : INSN_LOCATION (peepinsn));
3985 : 2110451 : if (JUMP_P (peepinsn) && JUMP_P (last))
3986 : 2977 : CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn);
3987 : 2110451 : before_try = PREV_INSN (insn);
3988 : 2110451 : delete_insn_chain (insn, peep2_insn_data[i].insn, false);
3989 : :
3990 : : /* Re-insert the EH_REGION notes. */
3991 : 2110451 : if (eh_note || (was_call && nonlocal_goto_handler_labels))
3992 : : {
3993 : 559 : edge eh_edge;
3994 : 559 : edge_iterator ei;
3995 : :
3996 : 1079 : FOR_EACH_EDGE (eh_edge, ei, bb->succs)
3997 : 565 : if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
3998 : : break;
3999 : :
4000 : 559 : if (eh_note)
4001 : 559 : copy_reg_eh_region_note_backward (eh_note, last, before_try);
4002 : :
4003 : 559 : if (eh_edge)
4004 : 136 : for (x = last; x != before_try; x = PREV_INSN (x))
4005 : 91 : if (x != BB_END (bb)
4006 : 91 : && (can_throw_internal (x)
4007 : 46 : || can_nonlocal_goto (x)))
4008 : : {
4009 : 1 : edge nfte, nehe;
4010 : 1 : int flags;
4011 : :
4012 : 1 : nfte = split_block (bb, x);
4013 : 1 : flags = (eh_edge->flags
4014 : : & (EDGE_EH | EDGE_ABNORMAL));
4015 : 1 : if (CALL_P (x))
4016 : 0 : flags |= EDGE_ABNORMAL_CALL;
4017 : 1 : nehe = make_edge (nfte->src, eh_edge->dest,
4018 : : flags);
4019 : :
4020 : 1 : nehe->probability = eh_edge->probability;
4021 : 1 : nfte->probability = nehe->probability.invert ();
4022 : :
4023 : 1 : peep2_do_cleanup_cfg |= purge_dead_edges (nfte->dest);
4024 : 1 : bb = nfte->src;
4025 : 1 : eh_edge = nehe;
4026 : : }
4027 : :
4028 : : /* Converting possibly trapping insn to non-trapping is
4029 : : possible. Zap dummy outgoing edges. */
4030 : 559 : peep2_do_cleanup_cfg |= purge_dead_edges (bb);
4031 : : }
4032 : :
4033 : : /* Re-insert the ARGS_SIZE notes. */
4034 : 2110451 : if (as_note)
4035 : 116085 : fixup_args_size_notes (before_try, last, get_args_size (as_note));
4036 : :
4037 : : /* Scan the new insns for embedded side effects and add appropriate
4038 : : REG_INC notes. */
4039 : : if (AUTO_INC_DEC)
4040 : : for (x = last; x != before_try; x = PREV_INSN (x))
4041 : : if (NONDEBUG_INSN_P (x))
4042 : : add_auto_inc_notes (x, PATTERN (x));
4043 : :
4044 : : /* If we generated a jump instruction, it won't have
4045 : : JUMP_LABEL set. Recompute after we're done. */
4046 : 4922978 : for (x = last; x != before_try; x = PREV_INSN (x))
4047 : 2815504 : if (JUMP_P (x))
4048 : : {
4049 : 2977 : peep2_do_rebuild_jump_labels = true;
4050 : 2977 : break;
4051 : : }
4052 : :
4053 : : return last;
4054 : : }
4055 : :
4056 : : /* After performing a replacement in basic block BB, fix up the life
4057 : : information in our buffer. LAST is the last of the insns that we
4058 : : emitted as a replacement. PREV is the insn before the start of
4059 : : the replacement. MATCH_LEN + 1 is the number of instructions that were
4060 : : matched, and which now need to be replaced in the buffer. */
4061 : :
4062 : : static void
4063 : 2110451 : peep2_update_life (basic_block bb, int match_len, rtx_insn *last,
4064 : : rtx_insn *prev)
4065 : : {
4066 : 2110451 : int i = peep2_buf_position (peep2_current + match_len + 1);
4067 : 2110451 : rtx_insn *x;
4068 : 2110451 : regset_head live;
4069 : :
4070 : 2110451 : INIT_REG_SET (&live);
4071 : 2110451 : COPY_REG_SET (&live, peep2_insn_data[i].live_before);
4072 : :
4073 : 2110451 : gcc_assert (peep2_current_count >= match_len + 1);
4074 : 2110451 : peep2_current_count -= match_len + 1;
4075 : :
4076 : 2110451 : x = last;
4077 : 2818367 : do
4078 : : {
4079 : 2818367 : if (INSN_P (x))
4080 : : {
4081 : 2818366 : df_insn_rescan (x);
4082 : 2818366 : if (peep2_current_count < MAX_INSNS_PER_PEEP2)
4083 : : {
4084 : 2677045 : peep2_current_count++;
4085 : 2677045 : if (--i < 0)
4086 : 735432 : i = MAX_INSNS_PER_PEEP2;
4087 : 2677045 : peep2_insn_data[i].insn = x;
4088 : 2677045 : df_simulate_one_insn_backwards (bb, x, &live);
4089 : 2677045 : COPY_REG_SET (peep2_insn_data[i].live_before, &live);
4090 : : }
4091 : : }
4092 : 2818367 : x = PREV_INSN (x);
4093 : : }
4094 : 2818367 : while (x != prev);
4095 : 2110451 : CLEAR_REG_SET (&live);
4096 : :
4097 : 2110451 : peep2_current = i;
4098 : 2110451 : }
4099 : :
4100 : : /* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.
4101 : : Return true if we added it, false otherwise. The caller will try to match
4102 : : peepholes against the buffer if we return false; otherwise it will try to
4103 : : add more instructions to the buffer. */
4104 : :
4105 : : static bool
4106 : 76962293 : peep2_fill_buffer (basic_block bb, rtx_insn *insn, regset live)
4107 : : {
4108 : 76962293 : int pos;
4109 : :
4110 : : /* Once we have filled the maximum number of insns the buffer can hold,
4111 : : allow the caller to match the insns against peepholes. We wait until
4112 : : the buffer is full in case the target has similar peepholes of different
4113 : : length; we always want to match the longest if possible. */
4114 : 76962293 : if (peep2_current_count == MAX_INSNS_PER_PEEP2)
4115 : : return false;
4116 : :
4117 : : /* If an insn has RTX_FRAME_RELATED_P set, do not allow it to be matched with
4118 : : any other pattern, lest it change the semantics of the frame info. */
4119 : 59100399 : if (RTX_FRAME_RELATED_P (insn))
4120 : : {
4121 : : /* Let the buffer drain first. */
4122 : 7744105 : if (peep2_current_count > 0)
4123 : : return false;
4124 : : /* Now the insn will be the only thing in the buffer. */
4125 : : }
4126 : :
4127 : 54820926 : pos = peep2_buf_position (peep2_current + peep2_current_count);
4128 : 54820926 : peep2_insn_data[pos].insn = insn;
4129 : 54820926 : COPY_REG_SET (peep2_insn_data[pos].live_before, live);
4130 : 54820926 : peep2_current_count++;
4131 : :
4132 : 54820926 : df_simulate_one_insn_forwards (bb, insn, live);
4133 : 54820926 : return true;
4134 : : }
4135 : :
4136 : : /* Perform the peephole2 optimization pass. */
4137 : :
4138 : : static void
4139 : 914371 : peephole2_optimize (void)
4140 : : {
4141 : 914371 : rtx_insn *insn;
4142 : 914371 : bitmap live;
4143 : 914371 : int i;
4144 : 914371 : basic_block bb;
4145 : :
4146 : 914371 : peep2_do_cleanup_cfg = false;
4147 : 914371 : peep2_do_rebuild_jump_labels = false;
4148 : :
4149 : 914371 : df_set_flags (DF_LR_RUN_DCE);
4150 : 914371 : df_note_add_problem ();
4151 : 914371 : df_analyze ();
4152 : :
4153 : : /* Initialize the regsets we're going to use. */
4154 : 8229339 : for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
4155 : 6400597 : peep2_insn_data[i].live_before = BITMAP_ALLOC (®_obstack);
4156 : 914371 : search_ofs = 0;
4157 : 914371 : live = BITMAP_ALLOC (®_obstack);
4158 : :
4159 : 10702050 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
4160 : : {
4161 : 9787679 : bool past_end = false;
4162 : 9787679 : int pos;
4163 : :
4164 : 9787679 : rtl_profile_for_bb (bb);
4165 : :
4166 : : /* Start up propagation. */
4167 : 19575358 : bitmap_copy (live, DF_LR_IN (bb));
4168 : 9787679 : df_simulate_initialize_forwards (bb, live);
4169 : 9787679 : peep2_reinit_state (live);
4170 : :
4171 : 9787679 : insn = BB_HEAD (bb);
4172 : 181394255 : for (;;)
4173 : : {
4174 : 181394255 : rtx_insn *attempt, *head;
4175 : 181394255 : int match_len;
4176 : :
4177 : 181394255 : if (!past_end && !NONDEBUG_INSN_P (insn))
4178 : : {
4179 : 59510068 : next_insn:
4180 : 114330994 : insn = NEXT_INSN (insn);
4181 : 114330994 : if (insn == NEXT_INSN (BB_END (bb)))
4182 : 9787679 : past_end = true;
4183 : 116441445 : continue;
4184 : : }
4185 : 76962293 : if (!past_end && peep2_fill_buffer (bb, insn, live))
4186 : 54820926 : goto next_insn;
4187 : :
4188 : : /* If we did not fill an empty buffer, it signals the end of the
4189 : : block. */
4190 : 67063261 : if (peep2_current_count == 0)
4191 : : break;
4192 : :
4193 : : /* The buffer filled to the current maximum, so try to match. */
4194 : :
4195 : 57275582 : pos = peep2_buf_position (peep2_current + peep2_current_count);
4196 : 57275582 : peep2_insn_data[pos].insn = PEEP2_EOB;
4197 : 57275582 : COPY_REG_SET (peep2_insn_data[pos].live_before, live);
4198 : :
4199 : : /* Match the peephole. */
4200 : 57275582 : head = peep2_insn_data[peep2_current].insn;
4201 : 57275582 : attempt = peephole2_insns (PATTERN (head), head, &match_len);
4202 : 57275582 : if (attempt != NULL)
4203 : : {
4204 : 2113002 : rtx_insn *last = peep2_attempt (bb, head, match_len, attempt);
4205 : 2113002 : if (last)
4206 : : {
4207 : 2110451 : peep2_update_life (bb, match_len, last, PREV_INSN (attempt));
4208 : 2110451 : continue;
4209 : : }
4210 : : }
4211 : :
4212 : : /* No match: advance the buffer by one insn. */
4213 : 55165131 : peep2_current = peep2_buf_position (peep2_current + 1);
4214 : 55165131 : peep2_current_count--;
4215 : : }
4216 : : }
4217 : :
4218 : 914371 : default_rtl_profile ();
4219 : 8229339 : for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
4220 : 6400597 : BITMAP_FREE (peep2_insn_data[i].live_before);
4221 : 914371 : BITMAP_FREE (live);
4222 : 914371 : if (peep2_do_rebuild_jump_labels)
4223 : 2148 : rebuild_jump_labels (get_insns ());
4224 : 914371 : if (peep2_do_cleanup_cfg)
4225 : 0 : cleanup_cfg (CLEANUP_CFG_CHANGED);
4226 : 914371 : }
4227 : :
4228 : : /* Common predicates for use with define_bypass. */
4229 : :
4230 : : /* Helper function for store_data_bypass_p, handle just a single SET
4231 : : IN_SET. */
4232 : :
4233 : : static bool
4234 : 0 : store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
4235 : : {
4236 : 0 : if (!MEM_P (SET_DEST (in_set)))
4237 : : return false;
4238 : :
4239 : 0 : rtx out_set = single_set (out_insn);
4240 : 0 : if (out_set)
4241 : 0 : return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
4242 : :
4243 : 0 : rtx out_pat = PATTERN (out_insn);
4244 : 0 : if (GET_CODE (out_pat) != PARALLEL)
4245 : : return false;
4246 : :
4247 : 0 : for (int i = 0; i < XVECLEN (out_pat, 0); i++)
4248 : : {
4249 : 0 : rtx out_exp = XVECEXP (out_pat, 0, i);
4250 : :
4251 : 0 : if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
4252 : 0 : continue;
4253 : :
4254 : 0 : gcc_assert (GET_CODE (out_exp) == SET);
4255 : :
4256 : 0 : if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
4257 : : return false;
4258 : : }
4259 : :
4260 : : return true;
4261 : : }
4262 : :
4263 : : /* True if the dependency between OUT_INSN and IN_INSN is on the store
4264 : : data not the address operand(s) of the store. IN_INSN and OUT_INSN
4265 : : must be either a single_set or a PARALLEL with SETs inside. */
4266 : :
4267 : : bool
4268 : 0 : store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4269 : : {
4270 : 0 : rtx in_set = single_set (in_insn);
4271 : 0 : if (in_set)
4272 : 0 : return store_data_bypass_p_1 (out_insn, in_set);
4273 : :
4274 : 0 : rtx in_pat = PATTERN (in_insn);
4275 : 0 : if (GET_CODE (in_pat) != PARALLEL)
4276 : : return false;
4277 : :
4278 : 0 : for (int i = 0; i < XVECLEN (in_pat, 0); i++)
4279 : : {
4280 : 0 : rtx in_exp = XVECEXP (in_pat, 0, i);
4281 : :
4282 : 0 : if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
4283 : 0 : continue;
4284 : :
4285 : 0 : gcc_assert (GET_CODE (in_exp) == SET);
4286 : :
4287 : 0 : if (!store_data_bypass_p_1 (out_insn, in_exp))
4288 : : return false;
4289 : : }
4290 : :
4291 : : return true;
4292 : : }
4293 : :
4294 : : /* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
4295 : : condition, and not the THEN or ELSE branch. OUT_INSN may be either a single
4296 : : or multiple set; IN_INSN should be single_set for truth, but for convenience
4297 : : of insn categorization may be any JUMP or CALL insn. */
4298 : :
4299 : : bool
4300 : 0 : if_test_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4301 : : {
4302 : 0 : rtx out_set, in_set;
4303 : :
4304 : 0 : in_set = single_set (in_insn);
4305 : 0 : if (! in_set)
4306 : : {
4307 : 0 : gcc_assert (JUMP_P (in_insn) || CALL_P (in_insn));
4308 : : return false;
4309 : : }
4310 : :
4311 : 0 : if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
4312 : : return false;
4313 : 0 : in_set = SET_SRC (in_set);
4314 : :
4315 : 0 : out_set = single_set (out_insn);
4316 : 0 : if (out_set)
4317 : : {
4318 : 0 : if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
4319 : 0 : || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
4320 : 0 : return false;
4321 : : }
4322 : : else
4323 : : {
4324 : 0 : rtx out_pat;
4325 : 0 : int i;
4326 : :
4327 : 0 : out_pat = PATTERN (out_insn);
4328 : 0 : gcc_assert (GET_CODE (out_pat) == PARALLEL);
4329 : :
4330 : 0 : for (i = 0; i < XVECLEN (out_pat, 0); i++)
4331 : : {
4332 : 0 : rtx exp = XVECEXP (out_pat, 0, i);
4333 : :
4334 : 0 : if (GET_CODE (exp) == CLOBBER)
4335 : 0 : continue;
4336 : :
4337 : 0 : gcc_assert (GET_CODE (exp) == SET);
4338 : :
4339 : 0 : if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
4340 : 0 : || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
4341 : 0 : return false;
4342 : : }
4343 : : }
4344 : :
4345 : : return true;
4346 : : }
4347 : :
4348 : : static unsigned int
4349 : 914371 : rest_of_handle_peephole2 (void)
4350 : : {
4351 : 914371 : if (HAVE_peephole2)
4352 : 0 : peephole2_optimize ();
4353 : :
4354 : 914371 : return 0;
4355 : : }
4356 : :
4357 : : namespace {
4358 : :
4359 : : const pass_data pass_data_peephole2 =
4360 : : {
4361 : : RTL_PASS, /* type */
4362 : : "peephole2", /* name */
4363 : : OPTGROUP_NONE, /* optinfo_flags */
4364 : : TV_PEEPHOLE2, /* tv_id */
4365 : : 0, /* properties_required */
4366 : : 0, /* properties_provided */
4367 : : 0, /* properties_destroyed */
4368 : : 0, /* todo_flags_start */
4369 : : TODO_df_finish, /* todo_flags_finish */
4370 : : };
4371 : :
4372 : : class pass_peephole2 : public rtl_opt_pass
4373 : : {
4374 : : public:
4375 : 281914 : pass_peephole2 (gcc::context *ctxt)
4376 : 563828 : : rtl_opt_pass (pass_data_peephole2, ctxt)
4377 : : {}
4378 : :
4379 : : /* opt_pass methods: */
4380 : : /* The epiphany backend creates a second instance of this pass, so we need
4381 : : a clone method. */
4382 : 0 : opt_pass * clone () final override { return new pass_peephole2 (m_ctxt); }
4383 : 1426773 : bool gate (function *) final override
4384 : : {
4385 : 1426773 : return (optimize > 0 && flag_peephole2);
4386 : : }
4387 : 914371 : unsigned int execute (function *) final override
4388 : : {
4389 : 914371 : return rest_of_handle_peephole2 ();
4390 : : }
4391 : :
4392 : : }; // class pass_peephole2
4393 : :
4394 : : } // anon namespace
4395 : :
4396 : : rtl_opt_pass *
4397 : 281914 : make_pass_peephole2 (gcc::context *ctxt)
4398 : : {
4399 : 281914 : return new pass_peephole2 (ctxt);
4400 : : }
4401 : :
4402 : : namespace {
4403 : :
4404 : : const pass_data pass_data_split_all_insns =
4405 : : {
4406 : : RTL_PASS, /* type */
4407 : : "split1", /* name */
4408 : : OPTGROUP_NONE, /* optinfo_flags */
4409 : : TV_NONE, /* tv_id */
4410 : : 0, /* properties_required */
4411 : : PROP_rtl_split_insns, /* properties_provided */
4412 : : 0, /* properties_destroyed */
4413 : : 0, /* todo_flags_start */
4414 : : 0, /* todo_flags_finish */
4415 : : };
4416 : :
4417 : : class pass_split_all_insns : public rtl_opt_pass
4418 : : {
4419 : : public:
4420 : 281914 : pass_split_all_insns (gcc::context *ctxt)
4421 : 563828 : : rtl_opt_pass (pass_data_split_all_insns, ctxt)
4422 : : {}
4423 : :
4424 : : /* opt_pass methods: */
4425 : : /* The epiphany backend creates a second instance of this pass, so
4426 : : we need a clone method. */
4427 : 0 : opt_pass * clone () final override
4428 : : {
4429 : 0 : return new pass_split_all_insns (m_ctxt);
4430 : : }
4431 : 1426762 : unsigned int execute (function *) final override
4432 : : {
4433 : 1426762 : split_all_insns ();
4434 : 1426762 : return 0;
4435 : : }
4436 : :
4437 : : }; // class pass_split_all_insns
4438 : :
4439 : : } // anon namespace
4440 : :
4441 : : rtl_opt_pass *
4442 : 281914 : make_pass_split_all_insns (gcc::context *ctxt)
4443 : : {
4444 : 281914 : return new pass_split_all_insns (ctxt);
4445 : : }
4446 : :
4447 : : namespace {
4448 : :
4449 : : const pass_data pass_data_split_after_reload =
4450 : : {
4451 : : RTL_PASS, /* type */
4452 : : "split2", /* name */
4453 : : OPTGROUP_NONE, /* optinfo_flags */
4454 : : TV_NONE, /* tv_id */
4455 : : 0, /* properties_required */
4456 : : 0, /* properties_provided */
4457 : : 0, /* properties_destroyed */
4458 : : 0, /* todo_flags_start */
4459 : : 0, /* todo_flags_finish */
4460 : : };
4461 : :
4462 : : class pass_split_after_reload : public rtl_opt_pass
4463 : : {
4464 : : public:
4465 : 281914 : pass_split_after_reload (gcc::context *ctxt)
4466 : 563828 : : rtl_opt_pass (pass_data_split_after_reload, ctxt)
4467 : : {}
4468 : :
4469 : : /* opt_pass methods: */
4470 : 1426773 : bool gate (function *) final override
4471 : : {
4472 : : /* If optimizing, then go ahead and split insns now. */
4473 : 1426773 : return optimize > 0;
4474 : : }
4475 : :
4476 : 987683 : unsigned int execute (function *) final override
4477 : : {
4478 : 987683 : split_all_insns ();
4479 : 987683 : return 0;
4480 : : }
4481 : :
4482 : : }; // class pass_split_after_reload
4483 : :
4484 : : } // anon namespace
4485 : :
4486 : : rtl_opt_pass *
4487 : 281914 : make_pass_split_after_reload (gcc::context *ctxt)
4488 : : {
4489 : 281914 : return new pass_split_after_reload (ctxt);
4490 : : }
4491 : :
4492 : : static bool
4493 : 2853546 : enable_split_before_sched2 (void)
4494 : : {
4495 : : #ifdef INSN_SCHEDULING
4496 : 1975368 : return optimize > 0 && flag_schedule_insns_after_reload;
4497 : : #else
4498 : : return false;
4499 : : #endif
4500 : : }
4501 : :
4502 : : namespace {
4503 : :
4504 : : const pass_data pass_data_split_before_sched2 =
4505 : : {
4506 : : RTL_PASS, /* type */
4507 : : "split3", /* name */
4508 : : OPTGROUP_NONE, /* optinfo_flags */
4509 : : TV_NONE, /* tv_id */
4510 : : 0, /* properties_required */
4511 : : 0, /* properties_provided */
4512 : : 0, /* properties_destroyed */
4513 : : 0, /* todo_flags_start */
4514 : : 0, /* todo_flags_finish */
4515 : : };
4516 : :
4517 : : class pass_split_before_sched2 : public rtl_opt_pass
4518 : : {
4519 : : public:
4520 : 281914 : pass_split_before_sched2 (gcc::context *ctxt)
4521 : 563828 : : rtl_opt_pass (pass_data_split_before_sched2, ctxt)
4522 : : {}
4523 : :
4524 : : /* opt_pass methods: */
4525 : 1426773 : bool gate (function *) final override
4526 : : {
4527 : 1426773 : return enable_split_before_sched2 ();
4528 : : }
4529 : :
4530 : 914378 : unsigned int execute (function *) final override
4531 : : {
4532 : 914378 : split_all_insns ();
4533 : 914378 : return 0;
4534 : : }
4535 : :
4536 : : }; // class pass_split_before_sched2
4537 : :
4538 : : } // anon namespace
4539 : :
4540 : : rtl_opt_pass *
4541 : 281914 : make_pass_split_before_sched2 (gcc::context *ctxt)
4542 : : {
4543 : 281914 : return new pass_split_before_sched2 (ctxt);
4544 : : }
4545 : :
4546 : : namespace {
4547 : :
4548 : : const pass_data pass_data_split_before_regstack =
4549 : : {
4550 : : RTL_PASS, /* type */
4551 : : "split4", /* name */
4552 : : OPTGROUP_NONE, /* optinfo_flags */
4553 : : TV_NONE, /* tv_id */
4554 : : 0, /* properties_required */
4555 : : 0, /* properties_provided */
4556 : : 0, /* properties_destroyed */
4557 : : 0, /* todo_flags_start */
4558 : : 0, /* todo_flags_finish */
4559 : : };
4560 : :
4561 : : class pass_split_before_regstack : public rtl_opt_pass
4562 : : {
4563 : : public:
4564 : 281914 : pass_split_before_regstack (gcc::context *ctxt)
4565 : 563828 : : rtl_opt_pass (pass_data_split_before_regstack, ctxt)
4566 : : {}
4567 : :
4568 : : /* opt_pass methods: */
4569 : : bool gate (function *) final override;
4570 : 512480 : unsigned int execute (function *) final override
4571 : : {
4572 : 512480 : split_all_insns ();
4573 : 512480 : return 0;
4574 : : }
4575 : :
4576 : : }; // class pass_split_before_regstack
4577 : :
4578 : : bool
4579 : 1426773 : pass_split_before_regstack::gate (function *)
4580 : : {
4581 : : #if HAVE_ATTR_length && defined (STACK_REGS)
4582 : : /* If flow2 creates new instructions which need splitting
4583 : : and scheduling after reload is not done, they might not be
4584 : : split until final which doesn't allow splitting
4585 : : if HAVE_ATTR_length. Selective scheduling can result in
4586 : : further instructions that need splitting. */
4587 : : #ifdef INSN_SCHEDULING
4588 : 2341152 : return !enable_split_before_sched2 () || flag_selective_scheduling2;
4589 : : #else
4590 : : return !enable_split_before_sched2 ();
4591 : : #endif
4592 : : #else
4593 : : return false;
4594 : : #endif
4595 : : }
4596 : :
4597 : : } // anon namespace
4598 : :
4599 : : rtl_opt_pass *
4600 : 281914 : make_pass_split_before_regstack (gcc::context *ctxt)
4601 : : {
4602 : 281914 : return new pass_split_before_regstack (ctxt);
4603 : : }
4604 : :
4605 : : namespace {
4606 : :
4607 : : const pass_data pass_data_split_for_shorten_branches =
4608 : : {
4609 : : RTL_PASS, /* type */
4610 : : "split5", /* name */
4611 : : OPTGROUP_NONE, /* optinfo_flags */
4612 : : TV_NONE, /* tv_id */
4613 : : 0, /* properties_required */
4614 : : 0, /* properties_provided */
4615 : : 0, /* properties_destroyed */
4616 : : 0, /* todo_flags_start */
4617 : : 0, /* todo_flags_finish */
4618 : : };
4619 : :
4620 : : class pass_split_for_shorten_branches : public rtl_opt_pass
4621 : : {
4622 : : public:
4623 : 281914 : pass_split_for_shorten_branches (gcc::context *ctxt)
4624 : 563828 : : rtl_opt_pass (pass_data_split_for_shorten_branches, ctxt)
4625 : : {}
4626 : :
4627 : : /* opt_pass methods: */
4628 : 1426773 : bool gate (function *) final override
4629 : : {
4630 : : /* The placement of the splitting that we do for shorten_branches
4631 : : depends on whether regstack is used by the target or not. */
4632 : : #if HAVE_ATTR_length && !defined (STACK_REGS)
4633 : : return true;
4634 : : #else
4635 : 1426773 : return false;
4636 : : #endif
4637 : : }
4638 : :
4639 : 0 : unsigned int execute (function *) final override
4640 : : {
4641 : 0 : split_all_insns_noflow ();
4642 : 0 : return 0;
4643 : : }
4644 : :
4645 : : }; // class pass_split_for_shorten_branches
4646 : :
4647 : : } // anon namespace
4648 : :
4649 : : rtl_opt_pass *
4650 : 281914 : make_pass_split_for_shorten_branches (gcc::context *ctxt)
4651 : : {
4652 : 281914 : return new pass_split_for_shorten_branches (ctxt);
4653 : : }
4654 : :
4655 : : /* (Re)initialize the target information after a change in target. */
4656 : :
4657 : : void
4658 : 211011 : recog_init ()
4659 : : {
4660 : : /* The information is zero-initialized, so we don't need to do anything
4661 : : first time round. */
4662 : 211011 : if (!this_target_recog->x_initialized)
4663 : : {
4664 : 208974 : this_target_recog->x_initialized = true;
4665 : 208974 : return;
4666 : : }
4667 : 2037 : memset (this_target_recog->x_bool_attr_masks, 0,
4668 : : sizeof (this_target_recog->x_bool_attr_masks));
4669 : 27444501 : for (unsigned int i = 0; i < NUM_INSN_CODES; ++i)
4670 : 27442464 : if (this_target_recog->x_op_alt[i])
4671 : : {
4672 : 29970 : free (this_target_recog->x_op_alt[i]);
4673 : 29970 : this_target_recog->x_op_alt[i] = 0;
4674 : : }
4675 : : }
|