1 /* Optimize jump instructions, for GNU compiler.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
20 /* This is the pathetic reminder of old fame of the jump-optimization pass
21 of the compiler. Now it contains basically a set of utility functions to
24 Each CODE_LABEL has a count of the times it is used
25 stored in the LABEL_NUSES internal field, and each JUMP_INSN
26 has one label that it refers to stored in the
27 JUMP_LABEL internal field. With this we can detect labels that
28 become unused because of the deletion of all the jumps that
29 formerly used them. The JUMP_LABEL info is sometimes looked
30 at by later passes. For return insns, it contains either a
31 RETURN or a SIMPLE_RETURN rtx.
33 The subroutines redirect_jump and invert_jump are used
34 from other passes as well. */
38 #include "coretypes.h"
44 #include "insn-config.h"
45 #include "insn-attr.h"
59 #include "diagnostic-core.h"
61 #include "tree-pass.h"
65 /* Optimize jump y; x: ... y: jumpif... x?
66 Don't know if it is worth bothering with. */
67 /* Optimize two cases of conditional jump to conditional jump?
68 This can never delete any instruction or make anything dead,
69 or even change what is live at any point.
70 So perhaps let combiner do it. */
72 static void init_label_info (rtx_insn
*);
73 static void mark_all_labels (rtx_insn
*);
74 static void mark_jump_label_1 (rtx
, rtx_insn
*, bool, bool);
75 static void mark_jump_label_asm (rtx
, rtx_insn
*);
76 static void redirect_exp_1 (rtx
*, rtx
, rtx
, rtx
);
77 static int invert_exp_1 (rtx
, rtx
);
79 /* Worker for rebuild_jump_labels and rebuild_jump_labels_chain. */
81 rebuild_jump_labels_1 (rtx_insn
*f
, bool count_forced
)
85 timevar_push (TV_REBUILD_JUMP
);
89 /* Keep track of labels used from static data; we don't track them
90 closely enough to delete them here, so make sure their reference
91 count doesn't drop to zero. */
94 for (insn
= forced_labels
; insn
; insn
= insn
->next ())
95 if (LABEL_P (insn
->insn ()))
96 LABEL_NUSES (insn
->insn ())++;
97 timevar_pop (TV_REBUILD_JUMP
);
100 /* This function rebuilds the JUMP_LABEL field and REG_LABEL_TARGET
101 notes in jumping insns and REG_LABEL_OPERAND notes in non-jumping
102 instructions and jumping insns that have labels as operands
103 (e.g. cbranchsi4). */
105 rebuild_jump_labels (rtx_insn
*f
)
107 rebuild_jump_labels_1 (f
, true);
110 /* This function is like rebuild_jump_labels, but doesn't run over
111 forced_labels. It can be used on insn chains that aren't the
112 main function chain. */
114 rebuild_jump_labels_chain (rtx_insn
*chain
)
116 rebuild_jump_labels_1 (chain
, false);
119 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
120 non-fallthru insn. This is not generally true, as multiple barriers
121 may have crept in, or the BARRIER may be separated from the last
122 real insn by one or more NOTEs.
124 This simple pass moves barriers and removes duplicates so that the
128 cleanup_barriers (void)
131 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
133 if (BARRIER_P (insn
))
135 rtx_insn
*prev
= prev_nonnote_insn (insn
);
141 /* Make sure we do not split a call and its corresponding
142 CALL_ARG_LOCATION note. */
143 rtx_insn
*next
= NEXT_INSN (prev
);
146 && NOTE_KIND (next
) == NOTE_INSN_CALL_ARG_LOCATION
)
150 if (BARRIER_P (prev
))
152 else if (prev
!= PREV_INSN (insn
))
154 basic_block bb
= BLOCK_FOR_INSN (prev
);
155 rtx_insn
*end
= PREV_INSN (insn
);
156 reorder_insns_nobb (insn
, insn
, prev
);
159 /* If the backend called in machine reorg compute_bb_for_insn
160 and didn't free_bb_for_insn again, preserve basic block
161 boundaries. Move the end of basic block to PREV since
162 it is followed by a barrier now, and clear BLOCK_FOR_INSN
163 on the following notes.
164 ??? Maybe the proper solution for the targets that have
165 cfg around after machine reorg is not to run cleanup_barriers
170 prev
= NEXT_INSN (prev
);
171 if (prev
!= insn
&& BLOCK_FOR_INSN (prev
) == bb
)
172 BLOCK_FOR_INSN (prev
) = NULL
;
184 const pass_data pass_data_cleanup_barriers
=
187 "barriers", /* name */
188 OPTGROUP_NONE
, /* optinfo_flags */
190 0, /* properties_required */
191 0, /* properties_provided */
192 0, /* properties_destroyed */
193 0, /* todo_flags_start */
194 0, /* todo_flags_finish */
197 class pass_cleanup_barriers
: public rtl_opt_pass
200 pass_cleanup_barriers (gcc::context
*ctxt
)
201 : rtl_opt_pass (pass_data_cleanup_barriers
, ctxt
)
204 /* opt_pass methods: */
205 virtual unsigned int execute (function
*) { return cleanup_barriers (); }
207 }; // class pass_cleanup_barriers
212 make_pass_cleanup_barriers (gcc::context
*ctxt
)
214 return new pass_cleanup_barriers (ctxt
);
218 /* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
219 for remaining targets for JUMP_P. Delete any REG_LABEL_OPERAND
220 notes whose labels don't occur in the insn any more. */
223 init_label_info (rtx_insn
*f
)
227 for (insn
= f
; insn
; insn
= NEXT_INSN (insn
))
230 LABEL_NUSES (insn
) = (LABEL_PRESERVE_P (insn
) != 0);
232 /* REG_LABEL_TARGET notes (including the JUMP_LABEL field) are
233 sticky and not reset here; that way we won't lose association
234 with a label when e.g. the source for a target register
235 disappears out of reach for targets that may use jump-target
236 registers. Jump transformations are supposed to transform
237 any REG_LABEL_TARGET notes. The target label reference in a
238 branch may disappear from the branch (and from the
239 instruction before it) for other reasons, like register
246 for (note
= REG_NOTES (insn
); note
; note
= next
)
248 next
= XEXP (note
, 1);
249 if (REG_NOTE_KIND (note
) == REG_LABEL_OPERAND
250 && ! reg_mentioned_p (XEXP (note
, 0), PATTERN (insn
)))
251 remove_note (insn
, note
);
257 /* A subroutine of mark_all_labels. Trivially propagate a simple label
258 load into a jump_insn that uses it. */
261 maybe_propagate_label_ref (rtx_insn
*jump_insn
, rtx_insn
*prev_nonjump_insn
)
263 rtx label_note
, pc
, pc_src
;
265 pc
= pc_set (jump_insn
);
266 pc_src
= pc
!= NULL
? SET_SRC (pc
) : NULL
;
267 label_note
= find_reg_note (prev_nonjump_insn
, REG_LABEL_OPERAND
, NULL
);
269 /* If the previous non-jump insn sets something to a label,
270 something that this jump insn uses, make that label the primary
271 target of this insn if we don't yet have any. That previous
272 insn must be a single_set and not refer to more than one label.
273 The jump insn must not refer to other labels as jump targets
274 and must be a plain (set (pc) ...), maybe in a parallel, and
275 may refer to the item being set only directly or as one of the
276 arms in an IF_THEN_ELSE. */
278 if (label_note
!= NULL
&& pc_src
!= NULL
)
280 rtx label_set
= single_set (prev_nonjump_insn
);
281 rtx label_dest
= label_set
!= NULL
? SET_DEST (label_set
) : NULL
;
283 if (label_set
!= NULL
284 /* The source must be the direct LABEL_REF, not a
285 PLUS, UNSPEC, IF_THEN_ELSE etc. */
286 && GET_CODE (SET_SRC (label_set
)) == LABEL_REF
287 && (rtx_equal_p (label_dest
, pc_src
)
288 || (GET_CODE (pc_src
) == IF_THEN_ELSE
289 && (rtx_equal_p (label_dest
, XEXP (pc_src
, 1))
290 || rtx_equal_p (label_dest
, XEXP (pc_src
, 2))))))
292 /* The CODE_LABEL referred to in the note must be the
293 CODE_LABEL in the LABEL_REF of the "set". We can
294 conveniently use it for the marker function, which
295 requires a LABEL_REF wrapping. */
296 gcc_assert (XEXP (label_note
, 0) == LABEL_REF_LABEL (SET_SRC (label_set
)));
298 mark_jump_label_1 (label_set
, jump_insn
, false, true);
300 gcc_assert (JUMP_LABEL (jump_insn
) == XEXP (label_note
, 0));
305 /* Mark the label each jump jumps to.
306 Combine consecutive labels, and count uses of labels. */
309 mark_all_labels (rtx_insn
*f
)
313 if (current_ir_type () == IR_RTL_CFGLAYOUT
)
316 FOR_EACH_BB_FN (bb
, cfun
)
318 /* In cfglayout mode, we don't bother with trivial next-insn
319 propagation of LABEL_REFs into JUMP_LABEL. This will be
320 handled by other optimizers using better algorithms. */
321 FOR_BB_INSNS (bb
, insn
)
323 gcc_assert (! insn
->deleted ());
324 if (NONDEBUG_INSN_P (insn
))
325 mark_jump_label (PATTERN (insn
), insn
, 0);
328 /* In cfglayout mode, there may be non-insns between the
329 basic blocks. If those non-insns represent tablejump data,
330 they contain label references that we must record. */
331 for (insn
= BB_HEADER (bb
); insn
; insn
= NEXT_INSN (insn
))
332 if (JUMP_TABLE_DATA_P (insn
))
333 mark_jump_label (PATTERN (insn
), insn
, 0);
334 for (insn
= BB_FOOTER (bb
); insn
; insn
= NEXT_INSN (insn
))
335 if (JUMP_TABLE_DATA_P (insn
))
336 mark_jump_label (PATTERN (insn
), insn
, 0);
341 rtx_insn
*prev_nonjump_insn
= NULL
;
342 for (insn
= f
; insn
; insn
= NEXT_INSN (insn
))
344 if (insn
->deleted ())
346 else if (LABEL_P (insn
))
347 prev_nonjump_insn
= NULL
;
348 else if (JUMP_TABLE_DATA_P (insn
))
349 mark_jump_label (PATTERN (insn
), insn
, 0);
350 else if (NONDEBUG_INSN_P (insn
))
352 mark_jump_label (PATTERN (insn
), insn
, 0);
355 if (JUMP_LABEL (insn
) == NULL
&& prev_nonjump_insn
!= NULL
)
356 maybe_propagate_label_ref (insn
, prev_nonjump_insn
);
359 prev_nonjump_insn
= insn
;
365 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
366 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
367 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
368 know whether it's source is floating point or integer comparison. Machine
369 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
370 to help this function avoid overhead in these cases. */
372 reversed_comparison_code_parts (enum rtx_code code
, const_rtx arg0
,
373 const_rtx arg1
, const_rtx insn
)
377 /* If this is not actually a comparison, we can't reverse it. */
378 if (GET_RTX_CLASS (code
) != RTX_COMPARE
379 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
)
382 mode
= GET_MODE (arg0
);
383 if (mode
== VOIDmode
)
384 mode
= GET_MODE (arg1
);
386 /* First see if machine description supplies us way to reverse the
387 comparison. Give it priority over everything else to allow
388 machine description to do tricks. */
389 if (GET_MODE_CLASS (mode
) == MODE_CC
390 && REVERSIBLE_CC_MODE (mode
))
392 #ifdef REVERSE_CONDITION
393 return REVERSE_CONDITION (code
, mode
);
395 return reverse_condition (code
);
399 /* Try a few special cases based on the comparison code. */
408 /* It is always safe to reverse EQ and NE, even for the floating
409 point. Similarly the unsigned comparisons are never used for
410 floating point so we can reverse them in the default way. */
411 return reverse_condition (code
);
416 /* In case we already see unordered comparison, we can be sure to
417 be dealing with floating point so we don't need any more tests. */
418 return reverse_condition_maybe_unordered (code
);
423 /* We don't have safe way to reverse these yet. */
429 if (GET_MODE_CLASS (mode
) == MODE_CC
|| CC0_P (arg0
))
431 /* Try to search for the comparison to determine the real mode.
432 This code is expensive, but with sane machine description it
433 will be never used, since REVERSIBLE_CC_MODE will return true
438 /* These CONST_CAST's are okay because prev_nonnote_insn just
439 returns its argument and we assign it to a const_rtx
441 for (rtx_insn
*prev
= prev_nonnote_insn (CONST_CAST_RTX (insn
));
442 prev
!= 0 && !LABEL_P (prev
);
443 prev
= prev_nonnote_insn (prev
))
445 const_rtx set
= set_of (arg0
, prev
);
446 if (set
&& GET_CODE (set
) == SET
447 && rtx_equal_p (SET_DEST (set
), arg0
))
449 rtx src
= SET_SRC (set
);
451 if (GET_CODE (src
) == COMPARE
)
453 rtx comparison
= src
;
454 arg0
= XEXP (src
, 0);
455 mode
= GET_MODE (arg0
);
456 if (mode
== VOIDmode
)
457 mode
= GET_MODE (XEXP (comparison
, 1));
460 /* We can get past reg-reg moves. This may be useful for model
461 of i387 comparisons that first move flag registers around. */
468 /* If register is clobbered in some ununderstandable way,
475 /* Test for an integer condition, or a floating-point comparison
476 in which NaNs can be ignored. */
477 if (CONST_INT_P (arg0
)
478 || (GET_MODE (arg0
) != VOIDmode
479 && GET_MODE_CLASS (mode
) != MODE_CC
480 && !HONOR_NANS (mode
)))
481 return reverse_condition (code
);
486 /* A wrapper around the previous function to take COMPARISON as rtx
487 expression. This simplifies many callers. */
489 reversed_comparison_code (const_rtx comparison
, const_rtx insn
)
491 if (!COMPARISON_P (comparison
))
493 return reversed_comparison_code_parts (GET_CODE (comparison
),
494 XEXP (comparison
, 0),
495 XEXP (comparison
, 1), insn
);
498 /* Return comparison with reversed code of EXP.
499 Return NULL_RTX in case we fail to do the reversal. */
501 reversed_comparison (const_rtx exp
, machine_mode mode
)
503 enum rtx_code reversed_code
= reversed_comparison_code (exp
, NULL_RTX
);
504 if (reversed_code
== UNKNOWN
)
507 return simplify_gen_relational (reversed_code
, mode
, VOIDmode
,
508 XEXP (exp
, 0), XEXP (exp
, 1));
512 /* Given an rtx-code for a comparison, return the code for the negated
513 comparison. If no such code exists, return UNKNOWN.
515 WATCH OUT! reverse_condition is not safe to use on a jump that might
516 be acting on the results of an IEEE floating point comparison, because
517 of the special treatment of non-signaling nans in comparisons.
518 Use reversed_comparison_code instead. */
521 reverse_condition (enum rtx_code code
)
563 /* Similar, but we're allowed to generate unordered comparisons, which
564 makes it safe for IEEE floating-point. Of course, we have to recognize
565 that the target will support them too... */
568 reverse_condition_maybe_unordered (enum rtx_code code
)
606 /* Similar, but return the code when two operands of a comparison are swapped.
607 This IS safe for IEEE floating-point. */
610 swap_condition (enum rtx_code code
)
652 /* Given a comparison CODE, return the corresponding unsigned comparison.
653 If CODE is an equality comparison or already an unsigned comparison,
657 unsigned_condition (enum rtx_code code
)
683 /* Similarly, return the signed version of a comparison. */
686 signed_condition (enum rtx_code code
)
712 /* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
713 truth of CODE1 implies the truth of CODE2. */
716 comparison_dominates_p (enum rtx_code code1
, enum rtx_code code2
)
718 /* UNKNOWN comparison codes can happen as a result of trying to revert
720 They can't match anything, so we have to reject them here. */
721 if (code1
== UNKNOWN
|| code2
== UNKNOWN
)
730 if (code2
== UNLE
|| code2
== UNGE
)
735 if (code2
== LE
|| code2
== LEU
|| code2
== GE
|| code2
== GEU
741 if (code2
== UNLE
|| code2
== NE
)
746 if (code2
== LE
|| code2
== NE
|| code2
== ORDERED
|| code2
== LTGT
)
751 if (code2
== UNGE
|| code2
== NE
)
756 if (code2
== GE
|| code2
== NE
|| code2
== ORDERED
|| code2
== LTGT
)
762 if (code2
== ORDERED
)
767 if (code2
== NE
|| code2
== ORDERED
)
772 if (code2
== LEU
|| code2
== NE
)
777 if (code2
== GEU
|| code2
== NE
)
782 if (code2
== NE
|| code2
== UNEQ
|| code2
== UNLE
|| code2
== UNLT
783 || code2
== UNGE
|| code2
== UNGT
)
794 /* Return 1 if INSN is an unconditional jump and nothing else. */
797 simplejump_p (const rtx_insn
*insn
)
799 return (JUMP_P (insn
)
800 && GET_CODE (PATTERN (insn
)) == SET
801 && GET_CODE (SET_DEST (PATTERN (insn
))) == PC
802 && GET_CODE (SET_SRC (PATTERN (insn
))) == LABEL_REF
);
805 /* Return nonzero if INSN is a (possibly) conditional jump
808 Use of this function is deprecated, since we need to support combined
809 branch and compare insns. Use any_condjump_p instead whenever possible. */
812 condjump_p (const rtx_insn
*insn
)
814 const_rtx x
= PATTERN (insn
);
816 if (GET_CODE (x
) != SET
817 || GET_CODE (SET_DEST (x
)) != PC
)
821 if (GET_CODE (x
) == LABEL_REF
)
824 return (GET_CODE (x
) == IF_THEN_ELSE
825 && ((GET_CODE (XEXP (x
, 2)) == PC
826 && (GET_CODE (XEXP (x
, 1)) == LABEL_REF
827 || ANY_RETURN_P (XEXP (x
, 1))))
828 || (GET_CODE (XEXP (x
, 1)) == PC
829 && (GET_CODE (XEXP (x
, 2)) == LABEL_REF
830 || ANY_RETURN_P (XEXP (x
, 2))))));
833 /* Return nonzero if INSN is a (possibly) conditional jump inside a
836 Use this function is deprecated, since we need to support combined
837 branch and compare insns. Use any_condjump_p instead whenever possible. */
840 condjump_in_parallel_p (const rtx_insn
*insn
)
842 const_rtx x
= PATTERN (insn
);
844 if (GET_CODE (x
) != PARALLEL
)
847 x
= XVECEXP (x
, 0, 0);
849 if (GET_CODE (x
) != SET
)
851 if (GET_CODE (SET_DEST (x
)) != PC
)
853 if (GET_CODE (SET_SRC (x
)) == LABEL_REF
)
855 if (GET_CODE (SET_SRC (x
)) != IF_THEN_ELSE
)
857 if (XEXP (SET_SRC (x
), 2) == pc_rtx
858 && (GET_CODE (XEXP (SET_SRC (x
), 1)) == LABEL_REF
859 || ANY_RETURN_P (XEXP (SET_SRC (x
), 1))))
861 if (XEXP (SET_SRC (x
), 1) == pc_rtx
862 && (GET_CODE (XEXP (SET_SRC (x
), 2)) == LABEL_REF
863 || ANY_RETURN_P (XEXP (SET_SRC (x
), 2))))
868 /* Return set of PC, otherwise NULL. */
871 pc_set (const rtx_insn
*insn
)
876 pat
= PATTERN (insn
);
878 /* The set is allowed to appear either as the insn pattern or
879 the first set in a PARALLEL. */
880 if (GET_CODE (pat
) == PARALLEL
)
881 pat
= XVECEXP (pat
, 0, 0);
882 if (GET_CODE (pat
) == SET
&& GET_CODE (SET_DEST (pat
)) == PC
)
888 /* Return true when insn is an unconditional direct jump,
889 possibly bundled inside a PARALLEL. */
892 any_uncondjump_p (const rtx_insn
*insn
)
894 const_rtx x
= pc_set (insn
);
897 if (GET_CODE (SET_SRC (x
)) != LABEL_REF
)
899 if (find_reg_note (insn
, REG_NON_LOCAL_GOTO
, NULL_RTX
))
904 /* Return true when insn is a conditional jump. This function works for
905 instructions containing PC sets in PARALLELs. The instruction may have
906 various other effects so before removing the jump you must verify
909 Note that unlike condjump_p it returns false for unconditional jumps. */
912 any_condjump_p (const rtx_insn
*insn
)
914 const_rtx x
= pc_set (insn
);
919 if (GET_CODE (SET_SRC (x
)) != IF_THEN_ELSE
)
922 a
= GET_CODE (XEXP (SET_SRC (x
), 1));
923 b
= GET_CODE (XEXP (SET_SRC (x
), 2));
925 return ((b
== PC
&& (a
== LABEL_REF
|| a
== RETURN
|| a
== SIMPLE_RETURN
))
927 && (b
== LABEL_REF
|| b
== RETURN
|| b
== SIMPLE_RETURN
)));
930 /* Return the label of a conditional jump. */
933 condjump_label (const rtx_insn
*insn
)
935 rtx x
= pc_set (insn
);
940 if (GET_CODE (x
) == LABEL_REF
)
942 if (GET_CODE (x
) != IF_THEN_ELSE
)
944 if (XEXP (x
, 2) == pc_rtx
&& GET_CODE (XEXP (x
, 1)) == LABEL_REF
)
946 if (XEXP (x
, 1) == pc_rtx
&& GET_CODE (XEXP (x
, 2)) == LABEL_REF
)
951 /* Return TRUE if INSN is a return jump. */
954 returnjump_p (const rtx_insn
*insn
)
958 subrtx_iterator::array_type array
;
959 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
962 switch (GET_CODE (x
))
970 if (SET_IS_RETURN_P (x
))
982 /* Return true if INSN is a (possibly conditional) return insn. */
985 eh_returnjump_p (rtx_insn
*insn
)
989 subrtx_iterator::array_type array
;
990 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
991 if (GET_CODE (*iter
) == EH_RETURN
)
997 /* Return true if INSN is a jump that only transfers control and
1001 onlyjump_p (const rtx_insn
*insn
)
1008 set
= single_set (insn
);
1011 if (GET_CODE (SET_DEST (set
)) != PC
)
1013 if (side_effects_p (SET_SRC (set
)))
1019 /* Return true iff INSN is a jump and its JUMP_LABEL is a label, not
1020 NULL or a return. */
1022 jump_to_label_p (const rtx_insn
*insn
)
1024 return (JUMP_P (insn
)
1025 && JUMP_LABEL (insn
) != NULL
&& !ANY_RETURN_P (JUMP_LABEL (insn
)));
1028 /* Return nonzero if X is an RTX that only sets the condition codes
1029 and has no side effects. */
1032 only_sets_cc0_p (const_rtx x
)
1040 return sets_cc0_p (x
) == 1 && ! side_effects_p (x
);
1043 /* Return 1 if X is an RTX that does nothing but set the condition codes
1044 and CLOBBER or USE registers.
1045 Return -1 if X does explicitly set the condition codes,
1046 but also does other things. */
1049 sets_cc0_p (const_rtx x
)
1057 if (GET_CODE (x
) == SET
&& SET_DEST (x
) == cc0_rtx
)
1059 if (GET_CODE (x
) == PARALLEL
)
1063 int other_things
= 0;
1064 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
1066 if (GET_CODE (XVECEXP (x
, 0, i
)) == SET
1067 && SET_DEST (XVECEXP (x
, 0, i
)) == cc0_rtx
)
1069 else if (GET_CODE (XVECEXP (x
, 0, i
)) == SET
)
1072 return ! sets_cc0
? 0 : other_things
? -1 : 1;
1077 /* Find all CODE_LABELs referred to in X, and increment their use
1078 counts. If INSN is a JUMP_INSN and there is at least one
1079 CODE_LABEL referenced in INSN as a jump target, then store the last
1080 one in JUMP_LABEL (INSN). For a tablejump, this must be the label
1081 for the ADDR_VEC. Store any other jump targets as REG_LABEL_TARGET
1082 notes. If INSN is an INSN or a CALL_INSN or non-target operands of
1083 a JUMP_INSN, and there is at least one CODE_LABEL referenced in
1084 INSN, add a REG_LABEL_OPERAND note containing that label to INSN.
1085 For returnjumps, the JUMP_LABEL will also be set as appropriate.
1087 Note that two labels separated by a loop-beginning note
1088 must be kept distinct if we have not yet done loop-optimization,
1089 because the gap between them is where loop-optimize
1090 will want to move invariant code to. CROSS_JUMP tells us
1091 that loop-optimization is done with. */
1094 mark_jump_label (rtx x
, rtx_insn
*insn
, int in_mem
)
1096 rtx asmop
= extract_asm_operands (x
);
1098 mark_jump_label_asm (asmop
, insn
);
1100 mark_jump_label_1 (x
, insn
, in_mem
!= 0,
1101 (insn
!= NULL
&& x
== PATTERN (insn
) && JUMP_P (insn
)));
1104 /* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs
1105 within a (MEM ...). IS_TARGET is TRUE when X is to be treated as a
1106 jump-target; when the JUMP_LABEL field of INSN should be set or a
1107 REG_LABEL_TARGET note should be added, not a REG_LABEL_OPERAND
1111 mark_jump_label_1 (rtx x
, rtx_insn
*insn
, bool in_mem
, bool is_target
)
1113 RTX_CODE code
= GET_CODE (x
);
1130 gcc_assert (JUMP_LABEL (insn
) == NULL
|| JUMP_LABEL (insn
) == x
);
1131 JUMP_LABEL (insn
) = x
;
1141 rtx_sequence
*seq
= as_a
<rtx_sequence
*> (x
);
1142 for (i
= 0; i
< seq
->len (); i
++)
1143 mark_jump_label (PATTERN (seq
->insn (i
)),
1152 /* If this is a constant-pool reference, see if it is a label. */
1153 if (CONSTANT_POOL_ADDRESS_P (x
))
1154 mark_jump_label_1 (get_pool_constant (x
), insn
, in_mem
, is_target
);
1157 /* Handle operands in the condition of an if-then-else as for a
1162 mark_jump_label_1 (XEXP (x
, 0), insn
, in_mem
, false);
1163 mark_jump_label_1 (XEXP (x
, 1), insn
, in_mem
, true);
1164 mark_jump_label_1 (XEXP (x
, 2), insn
, in_mem
, true);
1169 rtx label
= LABEL_REF_LABEL (x
);
1171 /* Ignore remaining references to unreachable labels that
1172 have been deleted. */
1174 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
)
1177 gcc_assert (LABEL_P (label
));
1179 /* Ignore references to labels of containing functions. */
1180 if (LABEL_REF_NONLOCAL_P (x
))
1183 LABEL_REF_LABEL (x
) = label
;
1184 if (! insn
|| ! insn
->deleted ())
1185 ++LABEL_NUSES (label
);
1190 /* Do not change a previous setting of JUMP_LABEL. If the
1191 JUMP_LABEL slot is occupied by a different label,
1192 create a note for this label. */
1193 && (JUMP_LABEL (insn
) == NULL
|| JUMP_LABEL (insn
) == label
))
1194 JUMP_LABEL (insn
) = label
;
1198 = is_target
? REG_LABEL_TARGET
: REG_LABEL_OPERAND
;
1200 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1201 for LABEL unless there already is one. All uses of
1202 a label, except for the primary target of a jump,
1203 must have such a note. */
1204 if (! find_reg_note (insn
, kind
, label
))
1205 add_reg_note (insn
, kind
, label
);
1211 /* Do walk the labels in a vector, but not the first operand of an
1212 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1215 if (! insn
->deleted ())
1217 int eltnum
= code
== ADDR_DIFF_VEC
? 1 : 0;
1219 for (i
= 0; i
< XVECLEN (x
, eltnum
); i
++)
1220 mark_jump_label_1 (XVECEXP (x
, eltnum
, i
), NULL
, in_mem
,
1229 fmt
= GET_RTX_FORMAT (code
);
1231 /* The primary target of a tablejump is the label of the ADDR_VEC,
1232 which is canonically mentioned *last* in the insn. To get it
1233 marked as JUMP_LABEL, we iterate over items in reverse order. */
1234 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1237 mark_jump_label_1 (XEXP (x
, i
), insn
, in_mem
, is_target
);
1238 else if (fmt
[i
] == 'E')
1242 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
1243 mark_jump_label_1 (XVECEXP (x
, i
, j
), insn
, in_mem
,
1249 /* Worker function for mark_jump_label. Handle asm insns specially.
1250 In particular, output operands need not be considered so we can
1251 avoid re-scanning the replicated asm_operand. Also, the asm_labels
1252 need to be considered targets. */
1255 mark_jump_label_asm (rtx asmop
, rtx_insn
*insn
)
1259 for (i
= ASM_OPERANDS_INPUT_LENGTH (asmop
) - 1; i
>= 0; --i
)
1260 mark_jump_label_1 (ASM_OPERANDS_INPUT (asmop
, i
), insn
, false, false);
1262 for (i
= ASM_OPERANDS_LABEL_LENGTH (asmop
) - 1; i
>= 0; --i
)
1263 mark_jump_label_1 (ASM_OPERANDS_LABEL (asmop
, i
), insn
, false, true);
1266 /* Delete insn INSN from the chain of insns and update label ref counts
1267 and delete insns now unreachable.
1269 Returns the first insn after INSN that was not deleted.
1271 Usage of this instruction is deprecated. Use delete_insn instead and
1272 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1275 delete_related_insns (rtx uncast_insn
)
1277 rtx_insn
*insn
= as_a
<rtx_insn
*> (uncast_insn
);
1278 int was_code_label
= (LABEL_P (insn
));
1280 rtx_insn
*next
= NEXT_INSN (insn
), *prev
= PREV_INSN (insn
);
1282 while (next
&& next
->deleted ())
1283 next
= NEXT_INSN (next
);
1285 /* This insn is already deleted => return first following nondeleted. */
1286 if (insn
->deleted ())
1291 /* If instruction is followed by a barrier,
1292 delete the barrier too. */
1294 if (next
!= 0 && BARRIER_P (next
))
1297 /* If this is a call, then we have to remove the var tracking note
1298 for the call arguments. */
1301 || (NONJUMP_INSN_P (insn
)
1302 && GET_CODE (PATTERN (insn
)) == SEQUENCE
1303 && CALL_P (XVECEXP (PATTERN (insn
), 0, 0))))
1307 for (p
= next
&& next
->deleted () ? NEXT_INSN (next
) : next
;
1310 if (NOTE_KIND (p
) == NOTE_INSN_CALL_ARG_LOCATION
)
1317 /* If deleting a jump, decrement the count of the label,
1318 and delete the label if it is now unused. */
1320 if (jump_to_label_p (insn
))
1322 rtx lab
= JUMP_LABEL (insn
);
1323 rtx_jump_table_data
*lab_next
;
1325 if (LABEL_NUSES (lab
) == 0)
1326 /* This can delete NEXT or PREV,
1327 either directly if NEXT is JUMP_LABEL (INSN),
1328 or indirectly through more levels of jumps. */
1329 delete_related_insns (lab
);
1330 else if (tablejump_p (insn
, NULL
, &lab_next
))
1332 /* If we're deleting the tablejump, delete the dispatch table.
1333 We may not be able to kill the label immediately preceding
1334 just yet, as it might be referenced in code leading up to
1336 delete_related_insns (lab_next
);
1340 /* Likewise if we're deleting a dispatch table. */
1342 if (rtx_jump_table_data
*table
= dyn_cast
<rtx_jump_table_data
*> (insn
))
1344 rtvec labels
= table
->get_labels ();
1346 int len
= GET_NUM_ELEM (labels
);
1348 for (i
= 0; i
< len
; i
++)
1349 if (LABEL_NUSES (XEXP (RTVEC_ELT (labels
, i
), 0)) == 0)
1350 delete_related_insns (XEXP (RTVEC_ELT (labels
, i
), 0));
1351 while (next
&& next
->deleted ())
1352 next
= NEXT_INSN (next
);
1356 /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1357 REG_LABEL_OPERAND or REG_LABEL_TARGET note. */
1359 for (note
= REG_NOTES (insn
); note
; note
= XEXP (note
, 1))
1360 if ((REG_NOTE_KIND (note
) == REG_LABEL_OPERAND
1361 || REG_NOTE_KIND (note
) == REG_LABEL_TARGET
)
1362 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1363 && LABEL_P (XEXP (note
, 0)))
1364 if (LABEL_NUSES (XEXP (note
, 0)) == 0)
1365 delete_related_insns (XEXP (note
, 0));
1367 while (prev
&& (prev
->deleted () || NOTE_P (prev
)))
1368 prev
= PREV_INSN (prev
);
1370 /* If INSN was a label and a dispatch table follows it,
1371 delete the dispatch table. The tablejump must have gone already.
1372 It isn't useful to fall through into a table. */
1375 && NEXT_INSN (insn
) != 0
1376 && JUMP_TABLE_DATA_P (NEXT_INSN (insn
)))
1377 next
= delete_related_insns (NEXT_INSN (insn
));
1379 /* If INSN was a label, delete insns following it if now unreachable. */
1381 if (was_code_label
&& prev
&& BARRIER_P (prev
))
1386 code
= GET_CODE (next
);
1388 next
= NEXT_INSN (next
);
1389 /* Keep going past other deleted labels to delete what follows. */
1390 else if (code
== CODE_LABEL
&& next
->deleted ())
1391 next
= NEXT_INSN (next
);
1392 /* Keep the (use (insn))s created by dbr_schedule, which needs
1393 them in order to track liveness relative to a previous
1395 else if (INSN_P (next
)
1396 && GET_CODE (PATTERN (next
)) == USE
1397 && INSN_P (XEXP (PATTERN (next
), 0)))
1398 next
= NEXT_INSN (next
);
1399 else if (code
== BARRIER
|| INSN_P (next
))
1400 /* Note: if this deletes a jump, it can cause more
1401 deletion of unreachable code, after a different label.
1402 As long as the value from this recursive call is correct,
1403 this invocation functions correctly. */
1404 next
= delete_related_insns (next
);
1410 /* I feel a little doubtful about this loop,
1411 but I see no clean and sure alternative way
1412 to find the first insn after INSN that is not now deleted.
1413 I hope this works. */
1414 while (next
&& next
->deleted ())
1415 next
= NEXT_INSN (next
);
1419 /* Delete a range of insns from FROM to TO, inclusive.
1420 This is for the sake of peephole optimization, so assume
1421 that whatever these insns do will still be done by a new
1422 peephole insn that will replace them. */
1425 delete_for_peephole (rtx_insn
*from
, rtx_insn
*to
)
1427 rtx_insn
*insn
= from
;
1431 rtx_insn
*next
= NEXT_INSN (insn
);
1432 rtx_insn
*prev
= PREV_INSN (insn
);
1436 insn
->set_deleted();
1438 /* Patch this insn out of the chain. */
1439 /* We don't do this all at once, because we
1440 must preserve all NOTEs. */
1442 SET_NEXT_INSN (prev
) = next
;
1445 SET_PREV_INSN (next
) = prev
;
1453 /* Note that if TO is an unconditional jump
1454 we *do not* delete the BARRIER that follows,
1455 since the peephole that replaces this sequence
1456 is also an unconditional jump in that case. */
1459 /* A helper function for redirect_exp_1; examines its input X and returns
1460 either a LABEL_REF around a label, or a RETURN if X was NULL. */
1462 redirect_target (rtx x
)
1466 if (!ANY_RETURN_P (x
))
1467 return gen_rtx_LABEL_REF (Pmode
, x
);
1471 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1472 NLABEL as a return. Accrue modifications into the change group. */
1475 redirect_exp_1 (rtx
*loc
, rtx olabel
, rtx nlabel
, rtx insn
)
1478 RTX_CODE code
= GET_CODE (x
);
1482 if ((code
== LABEL_REF
&& LABEL_REF_LABEL (x
) == olabel
)
1485 x
= redirect_target (nlabel
);
1486 if (GET_CODE (x
) == LABEL_REF
&& loc
== &PATTERN (insn
))
1487 x
= gen_rtx_SET (pc_rtx
, x
);
1488 validate_change (insn
, loc
, x
, 1);
1492 if (code
== SET
&& SET_DEST (x
) == pc_rtx
1493 && ANY_RETURN_P (nlabel
)
1494 && GET_CODE (SET_SRC (x
)) == LABEL_REF
1495 && LABEL_REF_LABEL (SET_SRC (x
)) == olabel
)
1497 validate_change (insn
, loc
, nlabel
, 1);
1501 if (code
== IF_THEN_ELSE
)
1503 /* Skip the condition of an IF_THEN_ELSE. We only want to
1504 change jump destinations, not eventual label comparisons. */
1505 redirect_exp_1 (&XEXP (x
, 1), olabel
, nlabel
, insn
);
1506 redirect_exp_1 (&XEXP (x
, 2), olabel
, nlabel
, insn
);
1510 fmt
= GET_RTX_FORMAT (code
);
1511 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1514 redirect_exp_1 (&XEXP (x
, i
), olabel
, nlabel
, insn
);
1515 else if (fmt
[i
] == 'E')
1518 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1519 redirect_exp_1 (&XVECEXP (x
, i
, j
), olabel
, nlabel
, insn
);
1524 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1525 the modifications into the change group. Return false if we did
1526 not see how to do that. */
1529 redirect_jump_1 (rtx_insn
*jump
, rtx nlabel
)
1531 int ochanges
= num_validated_changes ();
1534 gcc_assert (nlabel
!= NULL_RTX
);
1535 asmop
= extract_asm_operands (PATTERN (jump
));
1540 gcc_assert (ASM_OPERANDS_LABEL_LENGTH (asmop
) == 1);
1541 loc
= &ASM_OPERANDS_LABEL (asmop
, 0);
1543 else if (GET_CODE (PATTERN (jump
)) == PARALLEL
)
1544 loc
= &XVECEXP (PATTERN (jump
), 0, 0);
1546 loc
= &PATTERN (jump
);
1548 redirect_exp_1 (loc
, JUMP_LABEL (jump
), nlabel
, jump
);
1549 return num_validated_changes () > ochanges
;
1552 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
1553 jump target label is unused as a result, it and the code following
1556 Normally, NLABEL will be a label, but it may also be a RETURN rtx;
1557 in that case we are to turn the jump into a (possibly conditional)
1560 The return value will be 1 if the change was made, 0 if it wasn't
1561 (this can only occur when trying to produce return insns). */
1564 redirect_jump (rtx_jump_insn
*jump
, rtx nlabel
, int delete_unused
)
1566 rtx olabel
= jump
->jump_label ();
1570 /* If there is no label, we are asked to redirect to the EXIT block.
1571 When before the epilogue is emitted, return/simple_return cannot be
1572 created so we return 0 immediately. After the epilogue is emitted,
1573 we always expect a label, either a non-null label, or a
1574 return/simple_return RTX. */
1576 if (!epilogue_completed
)
1581 if (nlabel
== olabel
)
1584 if (! redirect_jump_1 (jump
, nlabel
) || ! apply_change_group ())
1587 redirect_jump_2 (jump
, olabel
, nlabel
, delete_unused
, 0);
1591 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1593 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1594 count has dropped to zero. */
1596 redirect_jump_2 (rtx_jump_insn
*jump
, rtx olabel
, rtx nlabel
, int delete_unused
,
1601 gcc_assert (JUMP_LABEL (jump
) == olabel
);
1603 /* Negative DELETE_UNUSED used to be used to signalize behavior on
1604 moving FUNCTION_END note. Just sanity check that no user still worry
1606 gcc_assert (delete_unused
>= 0);
1607 JUMP_LABEL (jump
) = nlabel
;
1608 if (!ANY_RETURN_P (nlabel
))
1609 ++LABEL_NUSES (nlabel
);
1611 /* Update labels in any REG_EQUAL note. */
1612 if ((note
= find_reg_note (jump
, REG_EQUAL
, NULL_RTX
)) != NULL_RTX
)
1614 if (ANY_RETURN_P (nlabel
)
1615 || (invert
&& !invert_exp_1 (XEXP (note
, 0), jump
)))
1616 remove_note (jump
, note
);
1619 redirect_exp_1 (&XEXP (note
, 0), olabel
, nlabel
, jump
);
1620 confirm_change_group ();
1624 /* Handle the case where we had a conditional crossing jump to a return
1625 label and are now changing it into a direct conditional return.
1626 The jump is no longer crossing in that case. */
1627 if (ANY_RETURN_P (nlabel
))
1628 CROSSING_JUMP_P (jump
) = 0;
1630 if (!ANY_RETURN_P (olabel
)
1631 && --LABEL_NUSES (olabel
) == 0 && delete_unused
> 0
1632 /* Undefined labels will remain outside the insn stream. */
1633 && INSN_UID (olabel
))
1634 delete_related_insns (olabel
);
1636 invert_br_probabilities (jump
);
1639 /* Invert the jump condition X contained in jump insn INSN. Accrue the
1640 modifications into the change group. Return nonzero for success. */
1642 invert_exp_1 (rtx x
, rtx insn
)
1644 RTX_CODE code
= GET_CODE (x
);
1646 if (code
== IF_THEN_ELSE
)
1648 rtx comp
= XEXP (x
, 0);
1650 enum rtx_code reversed_code
;
1652 /* We can do this in two ways: The preferable way, which can only
1653 be done if this is not an integer comparison, is to reverse
1654 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1655 of the IF_THEN_ELSE. If we can't do either, fail. */
1657 reversed_code
= reversed_comparison_code (comp
, insn
);
1659 if (reversed_code
!= UNKNOWN
)
1661 validate_change (insn
, &XEXP (x
, 0),
1662 gen_rtx_fmt_ee (reversed_code
,
1663 GET_MODE (comp
), XEXP (comp
, 0),
1670 validate_change (insn
, &XEXP (x
, 1), XEXP (x
, 2), 1);
1671 validate_change (insn
, &XEXP (x
, 2), tem
, 1);
1678 /* Invert the condition of the jump JUMP, and make it jump to label
1679 NLABEL instead of where it jumps now. Accrue changes into the
1680 change group. Return false if we didn't see how to perform the
1681 inversion and redirection. */
1684 invert_jump_1 (rtx_jump_insn
*jump
, rtx nlabel
)
1686 rtx x
= pc_set (jump
);
1690 ochanges
= num_validated_changes ();
1693 ok
= invert_exp_1 (SET_SRC (x
), jump
);
1696 if (num_validated_changes () == ochanges
)
1699 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1700 in Pmode, so checking this is not merely an optimization. */
1701 return nlabel
== JUMP_LABEL (jump
) || redirect_jump_1 (jump
, nlabel
);
1704 /* Invert the condition of the jump JUMP, and make it jump to label
1705 NLABEL instead of where it jumps now. Return true if successful. */
1708 invert_jump (rtx_jump_insn
*jump
, rtx nlabel
, int delete_unused
)
1710 rtx olabel
= JUMP_LABEL (jump
);
1712 if (invert_jump_1 (jump
, nlabel
) && apply_change_group ())
1714 redirect_jump_2 (jump
, olabel
, nlabel
, delete_unused
, 1);
1722 /* Like rtx_equal_p except that it considers two REGs as equal
1723 if they renumber to the same value and considers two commutative
1724 operations to be the same if the order of the operands has been
1728 rtx_renumbered_equal_p (const_rtx x
, const_rtx y
)
1731 const enum rtx_code code
= GET_CODE (x
);
1737 if ((code
== REG
|| (code
== SUBREG
&& REG_P (SUBREG_REG (x
))))
1738 && (REG_P (y
) || (GET_CODE (y
) == SUBREG
1739 && REG_P (SUBREG_REG (y
)))))
1741 int reg_x
= -1, reg_y
= -1;
1742 int byte_x
= 0, byte_y
= 0;
1743 struct subreg_info info
;
1745 if (GET_MODE (x
) != GET_MODE (y
))
1748 /* If we haven't done any renumbering, don't
1749 make any assumptions. */
1750 if (reg_renumber
== 0)
1751 return rtx_equal_p (x
, y
);
1755 reg_x
= REGNO (SUBREG_REG (x
));
1756 byte_x
= SUBREG_BYTE (x
);
1758 if (reg_renumber
[reg_x
] >= 0)
1760 subreg_get_info (reg_renumber
[reg_x
],
1761 GET_MODE (SUBREG_REG (x
)), byte_x
,
1762 GET_MODE (x
), &info
);
1763 if (!info
.representable_p
)
1765 reg_x
= info
.offset
;
1772 if (reg_renumber
[reg_x
] >= 0)
1773 reg_x
= reg_renumber
[reg_x
];
1776 if (GET_CODE (y
) == SUBREG
)
1778 reg_y
= REGNO (SUBREG_REG (y
));
1779 byte_y
= SUBREG_BYTE (y
);
1781 if (reg_renumber
[reg_y
] >= 0)
1783 subreg_get_info (reg_renumber
[reg_y
],
1784 GET_MODE (SUBREG_REG (y
)), byte_y
,
1785 GET_MODE (y
), &info
);
1786 if (!info
.representable_p
)
1788 reg_y
= info
.offset
;
1795 if (reg_renumber
[reg_y
] >= 0)
1796 reg_y
= reg_renumber
[reg_y
];
1799 return reg_x
>= 0 && reg_x
== reg_y
&& byte_x
== byte_y
;
1802 /* Now we have disposed of all the cases
1803 in which different rtx codes can match. */
1804 if (code
!= GET_CODE (y
))
1817 /* We can't assume nonlocal labels have their following insns yet. */
1818 if (LABEL_REF_NONLOCAL_P (x
) || LABEL_REF_NONLOCAL_P (y
))
1819 return LABEL_REF_LABEL (x
) == LABEL_REF_LABEL (y
);
1821 /* Two label-refs are equivalent if they point at labels
1822 in the same position in the instruction stream. */
1823 return (next_real_insn (LABEL_REF_LABEL (x
))
1824 == next_real_insn (LABEL_REF_LABEL (y
)));
1827 return XSTR (x
, 0) == XSTR (y
, 0);
1830 /* If we didn't match EQ equality above, they aren't the same. */
1837 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1839 if (GET_MODE (x
) != GET_MODE (y
))
1842 /* MEMs referring to different address space are not equivalent. */
1843 if (code
== MEM
&& MEM_ADDR_SPACE (x
) != MEM_ADDR_SPACE (y
))
1846 /* For commutative operations, the RTX match if the operand match in any
1847 order. Also handle the simple binary and unary cases without a loop. */
1848 if (targetm
.commutative_p (x
, UNKNOWN
))
1849 return ((rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0))
1850 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 1)))
1851 || (rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 1))
1852 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 0))));
1853 else if (NON_COMMUTATIVE_P (x
))
1854 return (rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0))
1855 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 1)));
1856 else if (UNARY_P (x
))
1857 return rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0));
1859 /* Compare the elements. If any pair of corresponding elements
1860 fail to match, return 0 for the whole things. */
1862 fmt
= GET_RTX_FORMAT (code
);
1863 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1869 if (XWINT (x
, i
) != XWINT (y
, i
))
1874 if (XINT (x
, i
) != XINT (y
, i
))
1876 if (((code
== ASM_OPERANDS
&& i
== 6)
1877 || (code
== ASM_INPUT
&& i
== 1)))
1884 if (XTREE (x
, i
) != XTREE (y
, i
))
1889 if (strcmp (XSTR (x
, i
), XSTR (y
, i
)))
1894 if (! rtx_renumbered_equal_p (XEXP (x
, i
), XEXP (y
, i
)))
1899 if (XEXP (x
, i
) != XEXP (y
, i
))
1906 if (XVECLEN (x
, i
) != XVECLEN (y
, i
))
1908 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
1909 if (!rtx_renumbered_equal_p (XVECEXP (x
, i
, j
), XVECEXP (y
, i
, j
)))
1920 /* If X is a hard register or equivalent to one or a subregister of one,
1921 return the hard register number. If X is a pseudo register that was not
1922 assigned a hard register, return the pseudo register number. Otherwise,
1923 return -1. Any rtx is valid for X. */
1926 true_regnum (const_rtx x
)
1930 if (REGNO (x
) >= FIRST_PSEUDO_REGISTER
1931 && (lra_in_progress
|| reg_renumber
[REGNO (x
)] >= 0))
1932 return reg_renumber
[REGNO (x
)];
1935 if (GET_CODE (x
) == SUBREG
)
1937 int base
= true_regnum (SUBREG_REG (x
));
1939 && base
< FIRST_PSEUDO_REGISTER
)
1941 struct subreg_info info
;
1943 subreg_get_info (lra_in_progress
1944 ? (unsigned) base
: REGNO (SUBREG_REG (x
)),
1945 GET_MODE (SUBREG_REG (x
)),
1946 SUBREG_BYTE (x
), GET_MODE (x
), &info
);
1948 if (info
.representable_p
)
1949 return base
+ info
.offset
;
1955 /* Return regno of the register REG and handle subregs too. */
1957 reg_or_subregno (const_rtx reg
)
1959 if (GET_CODE (reg
) == SUBREG
)
1960 reg
= SUBREG_REG (reg
);
1961 gcc_assert (REG_P (reg
));